├── License.txt
├── README.md
├── WindowsSandboxTools.psd1
├── WindowsSandboxTools.psm1
├── archive
├── README.txt
└── Start-WindowsSandbox.ps1
├── changelog.md
├── docs
├── Export-WsbConfiguration.md
├── Get-WsbConfiguration.md
├── New-WsbConfiguration.md
├── New-WsbMappedFolder.md
└── Start-WindowsSandbox.md
├── en-us
└── WindowsSandboxTools-help.xml
├── formats
└── wsbConfiguration.format.ps1xml
├── functions
├── Export-WsbConfiguration.ps1
├── Get-WsbConfiguration.ps1
├── New-WsbConfiguration.ps1
├── New-WsbMappedFolder.ps1
├── Start-WindowsSandbox.ps1
└── private.ps1
├── images
├── db.png
├── gazoo.bmp
├── sandbox.jpg
└── start-windowssandbox.png
├── wsbScripts
├── Install-VSCodeSandbox.ps1
├── README.md
├── Set-SandboxDesktop.ps1
├── basic.ps1
├── demo-config.ps1
├── demo.cmd
├── sandbox-basic.cmd
├── sandbox-config-pluralsight.ps1
├── sandbox-config-presentation.ps1
├── sandbox-config.ps1
├── sandbox-setup-pluralsight.cmd
├── sandbox-setup-presentation.cmd
├── sandbox-setup.cmd
└── sandbox-toast.ps1
└── wsbconfig
├── README.md
├── WinSandBx.wsb
├── basic.wsb
├── demo.wsb
├── pluralsight.wsb
├── presentation.wsb
├── sample.wsb
└── work.wsb
/License.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdhitsolutions/WindowsSandboxTools/9f2a0b71140b293c5769b939aac4899d26a1503b/License.txt
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Windows Sandbox Tools
2 |
3 | 
4 |
5 | [](https://www.powershellgallery.com/packages/WindowsSandboxTools/) [](https://www.powershellgallery.com/packages/WindowsSandboxTools/)
6 |
7 | This repository is a collection of PowerShell tools and scripts that I use to run and configure the Windows Sandbox feature that was introduced in Windows 10 2004. Many of the commands in this repository were first demonstrated on my [blog](https://jdhitsolutions.com/blog/powershell/7621/doing-more-with-windows-sandbox/). I strongly recommend you read the blog post before trying any of the code. As I mention in the blog post, most of the code here will __reduce the security__ of the Windows Sandbox application. This is a trade-off I am willing to make for the sake of functionality that meets *my* requirements. You have to decide how much of the code you would like to use.
8 |
9 | __*All code is offered as-is with no guarantees. Nothing in this repository should be considered production-ready or used in critical environments without your extensive testing and validation.*__
10 |
11 | ## Installing the Windows Sandbox
12 |
13 | You need to have the 2004 version of Windows 10 or later. The Windows Sandbox will run a containerized version of your operating system. I don't know off-hand if it is supported on Windows 10 Home or Education editions. Otherwise, you should be able to run these PowerShell commands to get started:
14 |
15 | ```powershell
16 | Get-WindowsOptionalFeature -Online -FeatureName Containers-DisposableClientVM
17 | Enable-WindowsOptionalFeature -Online -FeatureName Containers-DisposableClientVM
18 | ```
19 |
20 | ## The WindowsSandBoxTools Module
21 |
22 | I have created a PowerShell module called `WindowsSandBoxTools`. In this module are functions designed to make it easier to view a `wsb` configuration, create a new configuration, and export a configuration to a file. The module functions use several PowerShell class definitions.
23 |
24 | You can read the Microsoft documentation on creating a Windows Sandbox configuration at [https://docs.microsoft.com/windows/security/threat-protection/windows-sandbox/windows-sandbox-configure-using-wsb-file](https://docs.microsoft.com/windows/security/threat-protection/windows-sandbox/windows-sandbox-configure-using-wsb-file). The module commands are designed to abstract the process of creating the XML configuration files which have a `.wsb` extension.
25 |
26 | Install the module from the PowerShell Gallery.
27 |
28 | ```powershell
29 | Install-Module WindowsSandboxTools
30 | ```
31 |
32 | The module should work in Windows PowerShell and PowerShell 7 on Windows platforms.
33 |
34 | ### [Start-WindowsSandbox](docs/Start-WindowsSandbox.md)
35 |
36 | The [`Start-WindowsSandbox`](docs/Start-WindowsSandbox.mx) function is my primary tool. It has an alias of `wsb`. You can specify the path to the wsb file.
37 |
38 | 
39 |
40 | If you use the `NoSetup` parameter, it will launch the default Windows Sandbox. In either usage, you can specify display dimensions for the sandbox. The `WindowSize` parameter expects an array of width and height, like 1024,768. My default is 1920,1080. You may have to drag the window slightly to force the sandbox to redraw the screen and remove the horizontal scrollbar. Setting the display is tricky, and I don't know if what I am using will work for everyone, so if you don't get the results you expect, please post an issue.
41 |
42 | The sandbox will start and then minimize while any configurations you may have are executed.
43 |
44 | ### [Get-WsbConfiguration](docs/Get-WsbConfiguration.md)
45 |
46 | If you have created custom configurations, or intend to use the samples from this module, `Get-WsbConfiguration` will display information about the configuration.
47 |
48 | ```text
49 | PS C:\> Get-WsbConfiguration d:\wsb\simple.wsb
50 | WARNING: No value detected for LogonCommand. This may be intentional on your part.
51 |
52 |
53 | Name: Simple
54 |
55 | vGPU : Enable
56 | MemoryInMB : 8192
57 | AudioInput : Default
58 | VideoInput : Default
59 | ClipboardRedirection : Default
60 | PrinterRedirection : Default
61 | Networking : Default
62 | ProtectedClient : Default
63 | LogonCommand :
64 | MappedFolders : C:\scripts -> C:\scripts [RO:False]
65 | ```
66 |
67 | The command uses a custom format file to display the configuration. I have also found a way to insert metadata into the wsb file which (so far) doesn't appear to interfere with the Windows Sandbox application.
68 |
69 | ```text
70 | PS C:\> Get-WsbConfiguration d:\wsb\simple.wsb -MetadataOnly
71 |
72 | Author Name Description Updated
73 | ------ ---- ----------- -------
74 | Jeff Hicks Simple a simple configuration with mapping to C:\Scripts 12/10/2021 8:50:03 AM
75 | ```
76 |
77 | ### [New-WsbConfiguration](docs/New-WsbConfiguration.md)
78 |
79 | This is how you can create a new Windows Sandbox configuration.
80 |
81 | ```powershell
82 | $params = @{
83 | Networking = "Default"
84 | LogonCommand = "c:\data\demo.cmd"
85 | MemoryInMB = 2048
86 | PrinterRedirection = "Disable"
87 | MappedFolder = (New-WsbMappedFolder -HostFolder d:\data -SandboxFolder c:\data -ReadOnly)
88 | Name = "MyDemo"
89 | Description = "A demo WSB configuration"
90 | }
91 | $new = New-WsbConfiguration @params
92 | ```
93 |
94 | The `LogonCommand` value is relative to the WindowsSandbox. This code will create a `wsbConfiguration` object.
95 |
96 | ```text
97 |
98 | Name: MyDemo
99 |
100 | vGPU : Default
101 | MemoryInMB : 2048
102 | AudioInput : Default
103 | VideoInput : Default
104 | ClipboardRedirection : Default
105 | PrinterRedirection : Disable
106 | Networking : Default
107 | ProtectedClient : Default
108 | LogonCommand : c:\data\demo.cmd
109 | MappedFolders : d:\data -> c:\data [RO:True]
110 | ```
111 |
112 | You could modify this object as necessary.
113 |
114 | ```powershell
115 | $new.vGPU = "Enable"
116 | $new.Metadata.Updated = Get-Date
117 | ```
118 |
119 | The last step is to export the configuration to a `wsb` file.
120 |
121 | ```powershell
122 | $new | Export-WsbConfiguration -Path d:\wsb\demo.wsb
123 | ```
124 |
125 | Which will create this file:
126 |
127 | ```xml
128 |
129 |
130 | MyDemo
131 | Jeff
132 | A demo WSB configuration
133 | 07/10/2022 15:40:54
134 |
135 | Enable
136 | 2048
137 | Default
138 | Default
139 | Default
140 | Disable
141 | Default
142 | Default
143 |
144 | c:\data\demo.cmd
145 |
146 |
147 |
148 | d:\data
149 | c:\data
150 | True
151 |
152 |
153 |
154 | ```
155 |
156 | I can easily launch this configuration.
157 |
158 | ```powershell
159 | Start-WindowsSandbox -Configuration D:\wsb\demo.wsb
160 | ```
161 |
162 | ### [New-WsbMappedFolder](docs/New-WsbMappedFolder.md)
163 |
164 | Use this command to create a mapped folder object.
165 |
166 | ```powershell
167 | $map = New-WsbMappedFolder -HostFolder c:\work -SandboxFolder c:\work
168 | ```
169 |
170 | Once created, you can use this in a new configuration.
171 |
172 | ```powershell
173 | New-WsbConfiguration -Name work -MappedFolder $map -Description "Work sandbox"
174 | ```
175 |
176 | ### [Export-WSBConfiguration](docs/Export-WsbConfiguration.md)
177 |
178 | After you have created a new configuration, you will want to save it to a file.
179 |
180 | ```powershell
181 | New-WsbConfiguration -Name work -LogonCommand "$wsbScripts\basic.cmd" -MemoryInMB (4096*2) -MappedFolder (New-WsbMappedFolder -HostFolder d:\work -SandboxFolder c:\work) -Description "My work WSB configuration" | Export-WsbConfiguration -Path "$wsbConfigPath\work.wsb"
182 | ```
183 |
184 | The exported file must have a `.wsb` file extension. Save the file to your `$wsbConfigPath` location.
185 |
186 | You should get a file like this:
187 |
188 | ```xml
189 |
190 |
191 | work
192 | Jeff
193 | My work WSB configuration
194 | 07/18/2022 15:43:24
195 |
196 | Default
197 | 8192
198 | Default
199 | Default
200 | Default
201 | Default
202 | Default
203 | Default
204 |
205 | C:\scripts\windowssandboxtools\wsbScripts\basic.cmd
206 |
207 |
208 |
209 | c:\work
210 | c:\work
211 | False
212 |
213 |
214 |
215 | ```
216 |
217 | ## My Configuration Scripts
218 |
219 | My default [configuration script](wsbScripts/demo-config.ps1) takes about 4 minutes to complete. I use the [BurntToast](https://github.com/Windos/BurntToast) module to show a Windows Action Center notification when it is complete.
220 |
221 | When you import the module, it will define two global variables. `$wsbConfigPath` points to the location of your wsb files. `$wsbScripts` points to the location of your supporting scripts. By default, these variables will point to directories in the module root. You will most like want to update these variables to point to your location. I set this in my PowerShell profile script.
222 |
223 | __You need to verify and update path references if you use any of the configurations or scripts in this module.__
224 |
225 | ## RoadMap
226 |
227 | This is a list of items I'd like to address or handle more efficiently:
228 |
229 | + Look for a way to organize script components used for `LogonCommand` settings.
230 | + Use a default shared folder that can be a bit more generic.
231 | + Add a better way to provide or integrate toast notifications.
232 | + Create a graphical interface for creating configurations.
233 |
234 | Feel free to post enhancment suggestions in Issues.
235 |
--------------------------------------------------------------------------------
/WindowsSandboxTools.psd1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdhitsolutions/WindowsSandboxTools/9f2a0b71140b293c5769b939aac4899d26a1503b/WindowsSandboxTools.psd1
--------------------------------------------------------------------------------
/WindowsSandboxTools.psm1:
--------------------------------------------------------------------------------
1 | #turn on verbose output
2 | if ($MyInvocation.line -match "Verbose") {
3 | $VerbosePreference = "Continue"
4 | }
5 |
6 | #region class definitions
7 |
8 | Write-Verbose "Defining classes"
9 | #these need to be in the module file
10 | Class wsbMetadata {
11 | [string]$Author = $env:USERNAME
12 | [string]$Name
13 | [string]$Description
14 | [datetime]$Updated
15 |
16 | wsbMetadata([string]$Name) {
17 | $this.Name = $Name
18 | }
19 | wsbMetadata([string]$Name, [string]$Description) {
20 | $this.Name = $Name
21 | $this.Description = $Description
22 | }
23 | }
24 |
25 | Class wsbMappedFolder {
26 | [string]$HostFolder
27 | [string]$SandboxFolder
28 | [bool]$ReadOnly = $True
29 |
30 | wsbMappedFolder([string]$HostFolder, [string]$SandboxFolder, [bool]$ReadOnly) {
31 | $this.HostFolder = $HostFolder
32 | $this.SandboxFolder = $SandboxFolder
33 | $this.ReadOnly = $ReadOnly
34 | }
35 | }
36 |
37 | Class wsbConfiguration {
38 | [ValidateSet("Default", "Enable", "Disable")]
39 | [string]$vGPU = "Default"
40 | [string]$MemoryInMB = 4096
41 | [ValidateSet("Default", "Enable", "Disable")]
42 | [string]$AudioInput = "Default"
43 | [ValidateSet("Default", "Enable", "Disable")]
44 | [string]$VideoInput = "Default"
45 | [ValidateSet("Default", "Disable")]
46 | [string]$ClipboardRedirection = "Default"
47 | [ValidateSet("Default", "Enable", "Disable")]
48 | [string]$PrinterRedirection = "Default"
49 | [ValidateSet("Default", "Disable")]
50 | [string]$Networking = "Default"
51 | [ValidateSet("Default", "Enable", "Disable")]
52 | [string]$ProtectedClient = "Default"
53 | [string]$LogonCommand
54 | [wsbMappedFolder[]]$MappedFolder
55 | [wsbMetadata]$Metadata
56 | }
57 | #endregion
58 |
59 | #dot source the module functions
60 | Get-ChildItem -Path $psscriptroot\functions\*.ps1 |
61 | ForEach-Object {
62 | Write-Verbose "Dot source $($_.fullname)"
63 | . $_.fullname
64 | }
65 |
66 | #only define variables if they don't already exist.
67 | Write-Verbose "Configuring global variables"
68 | #define a global variable for the configuration directory
69 | Try {
70 | [void](Get-Variable -Name wsbConfigPath -Scope global -ErrorAction Stop)
71 | }
72 | Catch {
73 | $global:wsbConfigPath = "$psscriptroot\wsbconfig"
74 | }
75 |
76 | #define a global variable for configuration scripts
77 | Try {
78 | [void](Get-Variable -Name wsbScripts -Scope global -ErrorAction Stop)
79 | }
80 | Catch {
81 | $global:wsbScripts = "$psscriptroot\wsbScripts"
82 | }
83 |
84 | $msg = @"
85 | Using these global variables
86 |
87 | Windows Sandbox Tools
88 | ---------------------
89 |
90 | `$wsbConfigPath = $wsbConfigPath
91 | `$wsbScripts = $wsbScripts
92 |
93 | You may want to change these values.
94 |
95 | "@
96 |
97 | Write-Verbose $msg
98 |
99 | #Turn off module scoped Verbose output
100 | if ($VerbosePreference = "Continue") {
101 | $VerbosePreference = "SilentyContinue"
102 | }
--------------------------------------------------------------------------------
/archive/README.txt:
--------------------------------------------------------------------------------
1 | These are original script files that formed the foundation of this module.
--------------------------------------------------------------------------------
/archive/Start-WindowsSandbox.ps1:
--------------------------------------------------------------------------------
1 | Function Start-WindowsSandbox {
2 | [cmdletbinding(SupportsShouldProcess, DefaultParameterSetName = "config")]
3 | [alias("wsb")]
4 | [OutputType("none")]
5 |
6 | Param(
7 | [Parameter(Position = 0, ParameterSetName = "config", HelpMessage = "Specify the path to a wsb file.")]
8 | [ValidateScript( { Test-Path $_ })]
9 | #this is my default configuration
10 | [string]$Configuration = "c:\scripts\WindowsSandboxTools\WinSandBx.wsb",
11 | [Parameter(ParameterSetName = "normal", HelpMessage = "Start with no customizations.")]
12 | [switch]$NoSetup,
13 | [Parameter(HelpMessage = "Specify desktop resolutions as an array like 1280,720. The default is 1920,1080.")]
14 | [int[]]$WindowSize = @(1920, 1080)
15 | )
16 |
17 | Write-Verbose "Starting $($myinvocation.mycommand)"
18 |
19 | #dot source functions to change the window state and size
20 | . C:\scripts\WindowsSandboxTools\Set-WindowState.ps1
21 | . C:\scripts\WindowsSandboxTools\Set-MainWindowSize.ps1
22 |
23 | if ($NoSetup) {
24 | Write-Verbose "Launching default WindowsSandbox.exe"
25 | if ($PSCmdlet.shouldProcess("default configuration", "Launch Windows Sandbox")) {
26 | c:\windows\system32\WindowsSandbox.exe
27 | }
28 | }
29 | else {
30 | Write-Verbose "Launching WindowsSandbox using configuration file $Configuration"
31 |
32 | #create a file watcher if calling a configuration that uses it
33 | if ($Configuration -match "WinSandBx|presentation") {
34 | Write-Verbose "Registering a temporary file system watcher"
35 | #you can specify parameters for RegisterWatcher or modify the
36 | #file to use your own defaults.
37 | &$PSScriptroot\RegisterWatcher.ps1 | Out-Null
38 | }
39 |
40 | if ($PSCmdlet.shouldProcess($Configuration, "Launch Windows Sandbox")) {
41 | Start-Process -filepath $Configuration
42 | }
43 | }
44 |
45 | #WindowsSandbox.exe launches a child process, WindowsSandboxClient.
46 | #That is the process that needs to be minimized
47 | if ($pscmdlet.shouldProcess("WindowsSandboxClient", "Waiting for process")) {
48 |
49 | Write-Verbose "Waiting for child process WindowsSandboxClient"
50 | do {
51 | Start-Sleep -Seconds 1
52 | } Until (Get-Process -Name WindowsSandboxClient -ErrorAction SilentlyContinue)
53 |
54 | #give the process a chance to complete
55 | Start-Sleep -Seconds 5
56 | }
57 |
58 | Write-Verbose "Setting Window size to $($WindowSize -join 'x')"
59 | if ($pscmdlet.shouldProcess("WindowsSandboxClient", "Modifying Window size and state")) {
60 | $clientProc = Get-Process -Name WindowsSandboxClient
61 | #values to pass to the function are a percentage of the desired size
62 | [int]$width = $WindowSize[0]*.6667
63 | [int]$Height = $WindowSize[1]*.6667
64 |
65 | Set-WindowSize -handle $clientproc.MainWindowHandle -width $width -height $height
66 |
67 | #Configure the Windows Sandbox to run minimized (Issue #2)
68 | Write-Verbose "Minimizing child process WindowsSandboxClient"
69 | $clientProc | Set-WindowState -State minimize
70 | }
71 | Write-Verbose "Ending $($myinvocation.mycommand). Any script configurations will continue in the Windows Sandbox."
72 | Write-Host "Windows Sandbox has been launched. You may need to wait for any configurations to complete." -foregroundColor green
73 | }
74 |
75 |
--------------------------------------------------------------------------------
/changelog.md:
--------------------------------------------------------------------------------
1 | # Change Log for Windows SandBox Tools
2 |
3 | ## v1.1.0
4 |
5 | ### Changed
6 |
7 | - Updated license.
8 | - General code cleanup.
9 | - Updated help documentation.
10 | - Modified `Get-WSBConfiguration` to accept paths from the pipeline.
11 |
12 | ### Added
13 |
14 | - Added missing online help links
15 |
16 | ## v1.0.0
17 |
18 | + Updated `Start-WindowsSandbox` to not scale resolutions.
19 | + Fixed bug in `Start-WindowsSandbox` that was testing for a configuration when using the basic configuration. [Issue 4](https://github.com/jdhitsolutions/WindowsSandboxTools/issues/4)
20 | + Reorganized module layout.
21 | + Added my configurations and scripts.
22 | + Moved class definitions to the root module file.
23 | + Updated help documentation.
24 | + Updated `New-WsbMappedFolder` to use a switch for `-Readonly`.
25 | + Fixed bug where Verbose remained on if importing the module with `-Verbose`.
26 | + Updated `README.md`.
27 | + Published to the PowerShell Gallery
28 |
29 | ## December 14, 2020
30 |
31 | + Code cleanup for the sake of clarity.
32 | + Migrated commands to a module, `WindowsSandboxTools`.
33 | + Made `Configuration` parameter mandatory in `Start-WindowsSandbox`.
34 | + Fixed default logo path in `RegisterWatcher`.
35 | + Added timestamp to verbose messages in `Start-WindowsSandbox`.
36 | + Modified `Register-Watcher` to remove any left-over event subscriber.
37 | + Created a global variable `wsbConfigPath` which can be used to reference a centralized location for WSB files.
38 | + Created a global variable `wsbScripts` which can be used to reference a centralized location for scripts.
39 | + Added argument completer for the `Configuration` parameter in `Start-WindowsSandbox` and `Get-WsbConfiguration`.
40 | + Updated `Start-WindowsSandbox` to test if an instance is already running and display a warning if it is.
41 | + Updated setup scripts and sample configuration files.
42 |
43 | ## September 10, 2020
44 |
45 | + Changed default screen size in `Start-WindowsSandbox` to 1920x1080.
46 | + Created commands, `Get-WsbConfiguration`, `New-WsbConfiguration`, `New-WsbMappedFolder`, and `Export-WsbConfiguration` for creating and managing `wsb` files. The enhanced files can include metadata information. These functions are defined in a module file, `wsbFunctions.psm1`.
47 | + Created `wsbConfiguration.format.ps1xml` to display the `wsbConfiguration` object as a formatted list by default.
48 | + Fixed `Start-Process` parameter bug in `Start-WindowsSandbox`.
49 | + Modified `RegisterWatcher.ps1` to let the user define the flag file. The default is `C:\scripts\sandbox.flag`.
50 | + Modified `RegisterWatcher.ps1` to let the user define settings for the toast notifications. Defaults are mine.
51 | + Updated `Start-WindowsSandbox` to better handle `-Whatif` support.
52 | + Updated `README.md`
53 |
54 | ## August 31, 2020
55 |
56 | + Added code to minimize Windows Sandbox window when running a configuration. (Issue #2)
57 | + Minor tweaks to the WSB configuration files.
58 | + Added `-WhatIf` support to `Start-WindowsSandbox` and `RegisterWatcher.ps1`.
59 | + Added `Set-WindowState` function.
60 | + Modified `Sandbox-toast.ps1` to make the toast announcement silent.
61 | + Added Sound to local toast notification.
62 | + Added code to adjust the window size. This the closest I can get to setting a desktop resolution. (Issue #1)
63 | + Added presentation configurations and setup scripts.
64 |
65 | ## August 27, 2020
66 |
67 | + initial commit
68 | + Added `README.md`
69 | + Updated scripts to reflect the new path.
70 | + Added a file system watcher to send a toast notification when my configuration is complete.
71 |
--------------------------------------------------------------------------------
/docs/Export-WsbConfiguration.md:
--------------------------------------------------------------------------------
1 | ---
2 | external help file: WindowsSandboxTools-help.xml
3 | Module Name: WindowsSandboxTools
4 | online version: https://bit.ly/3PkXMvl
5 | schema: 2.0.0
6 | ---
7 |
8 | # Export-WsbConfiguration
9 |
10 | ## SYNOPSIS
11 |
12 | Export a WSB configuration to an XML file.
13 |
14 | ## SYNTAX
15 |
16 | ```yaml
17 | Export-WsbConfiguration [-Configuration] -Path [-NoClobber] [-WhatIf] [-Confirm][]
18 | ```
19 |
20 | ## DESCRIPTION
21 |
22 | This command will take an existing Windows Sandbox Configuration object and export it to an XML file.
23 |
24 | ## EXAMPLES
25 |
26 | ### Example 1
27 |
28 | ```powershell
29 | PS C:\> New-WsbConfiguration -Name demo -LogonCommand C:\scripts\wsbscripts\sandbox-basic.cmd -MemoryInMB (4096*2) -MappedFolder (New-WsbMappedFolder -HostFolder c:\scratch -SandboxFolder c:\junk) -Description "My test WSB configuration" | Export-WsbConfiguration -Path c:\scratch\scratch.wsb
30 | ```
31 |
32 | ## PARAMETERS
33 |
34 | ### -Configuration
35 |
36 | Specify a wsbConfiguration object.
37 |
38 | ```yaml
39 | Type: wsbConfiguration
40 | Parameter Sets: (All)
41 | Aliases:
42 |
43 | Required: True
44 | Position: 0
45 | Default value: None
46 | Accept pipeline input: True (ByValue)
47 | Accept wildcard characters: False
48 | ```
49 |
50 | ### -Confirm
51 |
52 | Prompts you for confirmation before running the cmdlet.
53 |
54 | ```yaml
55 | Type: SwitchParameter
56 | Parameter Sets: (All)
57 | Aliases: cf
58 |
59 | Required: False
60 | Position: Named
61 | Default value: None
62 | Accept pipeline input: False
63 | Accept wildcard characters: False
64 | ```
65 |
66 | ### -NoClobber
67 |
68 | Don't overwrite an existing file.
69 |
70 | ```yaml
71 | Type: SwitchParameter
72 | Parameter Sets: (All)
73 | Aliases:
74 |
75 | Required: False
76 | Position: Named
77 | Default value: None
78 | Accept pipeline input: False
79 | Accept wildcard characters: False
80 | ```
81 |
82 | ### -Path
83 |
84 | Specify the path and filename.
85 | It must end in .wsb
86 |
87 | ```yaml
88 | Type: String
89 | Parameter Sets: (All)
90 | Aliases:
91 |
92 | Required: True
93 | Position: Named
94 | Default value: None
95 | Accept pipeline input: False
96 | Accept wildcard characters: False
97 | ```
98 |
99 | ### -WhatIf
100 |
101 | Shows what would happen if the cmdlet runs.
102 | The cmdlet is not run.
103 |
104 | ```yaml
105 | Type: SwitchParameter
106 | Parameter Sets: (All)
107 | Aliases: wi
108 |
109 | Required: False
110 | Position: Named
111 | Default value: None
112 | Accept pipeline input: False
113 | Accept wildcard characters: False
114 | ```
115 |
116 | ### CommonParameters
117 |
118 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
119 |
120 | ## INPUTS
121 |
122 | ### wsbConfiguration
123 |
124 | ## OUTPUTS
125 |
126 | ### System.IO.FileInfo
127 |
128 | ## NOTES
129 |
130 | Learn more about PowerShell: http://jdhitsolutions.com/blog/essential-powershell-resources/
131 |
132 | ## RELATED LINKS
133 |
134 | [New-WsbConfiguration](New-WsbConfiguration.md)
135 |
--------------------------------------------------------------------------------
/docs/Get-WsbConfiguration.md:
--------------------------------------------------------------------------------
1 | ---
2 | external help file: WindowsSandboxTools-help.xml
3 | Module Name: WindowsSandboxTools
4 | online version: https://bit.ly/44aWC9X
5 | schema: 2.0.0
6 | ---
7 |
8 | # Get-WsbConfiguration
9 |
10 | ## SYNOPSIS
11 |
12 | Get a Windows Sandbox configuration.
13 |
14 | ## SYNTAX
15 |
16 | ```yaml
17 | Get-WsbConfiguration [-Path] [-MetadataOnly] []
18 | ```
19 |
20 | ## DESCRIPTION
21 |
22 | This command will give you information about a sandbox configuration.
23 |
24 | ## EXAMPLES
25 |
26 | ### Example 1
27 |
28 | ```powershell
29 | PS C:\> Get-WsbConfiguration C:\Scripts\WindowsSandboxTools\wsbConfig\dev.wsb
30 |
31 | Name: C:\scripts\wsbconfig\dev.wsb
32 |
33 | vGPU : Enable
34 | MemoryInMB : 8192
35 | AudioInput : Disable
36 | VideoInput : Default
37 | ClipboardRedirection : Default
38 | PrinterRedirection : Default
39 | Networking : Default
40 | ProtectedClient : Disable
41 | LogonCommand : C:\scripts\wsbScripts\sandbox-setup.cmd
42 | MappedFolders : C:\scripts -> C:\scripts [RO:False]
43 | C:\Pluralsight -> C:\Pluralsight [RO:True]
44 | ```
45 |
46 | ### Example 2
47 |
48 | ```powershell
49 | PS C:\> Get-WsbConfiguration C:\Scripts\WindowsSandboxTools\wsbConfig\dev.wsb -MetadataOnly
50 |
51 | Author Name Description Updated
52 | ------ ---- ----------- -------
53 | Jeff C:\scripts\wsbconfig\dev.wsb A test wsb file 12/10/2020 8:50:03 AM
54 | ```
55 |
56 | ## PARAMETERS
57 |
58 | ### -MetadataOnly
59 |
60 | Only display metadata information.
61 |
62 | ```yaml
63 | Type: SwitchParameter
64 | Parameter Sets: (All)
65 | Aliases:
66 |
67 | Required: False
68 | Position: Named
69 | Default value: None
70 | Accept pipeline input: False
71 | Accept wildcard characters: False
72 | ```
73 |
74 | ### -Path
75 |
76 | Specify the path to the .wsb file. The command will autocomplete to the $wsbConfigPath variable.
77 |
78 | ```yaml
79 | Type: String
80 | Parameter Sets: (All)
81 | Aliases:
82 |
83 | Required: True
84 | Position: 0
85 | Default value: None
86 | Accept pipeline input: True (ByValue)
87 | Accept wildcard characters: False
88 | ```
89 |
90 | ### CommonParameters
91 |
92 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
93 |
94 | ## INPUTS
95 |
96 | ### None
97 |
98 | ## OUTPUTS
99 |
100 | ### wsbConfiguration
101 |
102 | ## NOTES
103 |
104 | Learn more about PowerShell: http://jdhitsolutions.com/blog/essential-powershell-resources/
105 |
106 | ## RELATED LINKS
107 |
108 | [New-WsbConfiguration](New-WsbConfiguration.md)
109 |
--------------------------------------------------------------------------------
/docs/New-WsbConfiguration.md:
--------------------------------------------------------------------------------
1 | ---
2 | external help file: WindowsSandboxTools-help.xml
3 | Module Name: WindowsSandboxTools
4 | online version: https://bit.ly/3qSqCJA
5 | schema: 2.0.0
6 | ---
7 |
8 | # New-WsbConfiguration
9 |
10 | ## SYNOPSIS
11 |
12 | Create a new Windows Sandbox configuration.
13 |
14 | ## SYNTAX
15 |
16 | ### name (Default)
17 |
18 | ```yaml
19 | New-WsbConfiguration [-vGPU ] [-MemoryInMB ] [-AudioInput ] [-VideoInput ] [-ClipboardRedirection ] [-PrinterRedirection ] [-Networking ] [-ProtectedClient ] [-LogonCommand ] [-MappedFolder ] -Name [-Description ] [-Author ] []
20 | ```
21 |
22 | ### meta
23 |
24 | ```yaml
25 | New-WsbConfiguration [-vGPU ] [-MemoryInMB ] [-AudioInput ] [-VideoInput ] [-ClipboardRedirection ] [-PrinterRedirection ] [-Networking ] [-ProtectedClient ] [-LogonCommand ] [-MappedFolder ]
26 | [-Metadata ] []
27 | ```
28 |
29 | ## DESCRIPTION
30 |
31 | This command will create a new Wsbconfiguration object. Use Export-Wsbconfiguration to save it to disk.
32 |
33 | ## EXAMPLES
34 |
35 | ### Example 1
36 |
37 | ```powershell
38 | PS C:\> $new = New-WsbConfiguration -Name demo -LogonCommand C:\scripts\wsbscripts\sandbox-basic.cmd -MemoryInMB (4096*2) -MappedFolder (New-WsbMappedFolder -HostFolder c:\scratch -SandboxFolder c:\junk) -description "My scratch configuration"
39 | ```
40 |
41 | ## PARAMETERS
42 |
43 | ### -AudioInput
44 |
45 | ```yaml
46 | Type: String
47 | Parameter Sets: (All)
48 | Aliases:
49 | Accepted values: Default, Enable, Disable
50 |
51 | Required: False
52 | Position: Named
53 | Default value: Default
54 | Accept pipeline input: True (ByPropertyName)
55 | Accept wildcard characters: False
56 | ```
57 |
58 | ### -Author
59 |
60 | Who is the author?
61 |
62 | ```yaml
63 | Type: String
64 | Parameter Sets: name
65 | Aliases:
66 |
67 | Required: False
68 | Position: Named
69 | Default value: current user
70 | Accept pipeline input: False
71 | Accept wildcard characters: False
72 | ```
73 |
74 | ### -ClipboardRedirection
75 |
76 | ```yaml
77 | Type: String
78 | Parameter Sets: (All)
79 | Aliases:
80 | Accepted values: Default, Disable
81 |
82 | Required: False
83 | Position: Named
84 | Default value: Default
85 | Accept pipeline input: True (ByPropertyName)
86 | Accept wildcard characters: False
87 | ```
88 |
89 | ### -Description
90 |
91 | Provide a description for this configuration.
92 |
93 | ```yaml
94 | Type: String
95 | Parameter Sets: name
96 | Aliases:
97 |
98 | Required: False
99 | Position: Named
100 | Default value: None
101 | Accept pipeline input: False
102 | Accept wildcard characters: False
103 | ```
104 |
105 | ### -LogonCommand
106 |
107 | The path and file are relative to the Windows Sandbox configuration.
108 |
109 | ```yaml
110 | Type: Object
111 | Parameter Sets: (All)
112 | Aliases:
113 |
114 | Required: False
115 | Position: Named
116 | Default value: None
117 | Accept pipeline input: True (ByPropertyName)
118 | Accept wildcard characters: False
119 | ```
120 |
121 | ### -MappedFolder
122 |
123 | Specify a mapped folder object.
124 |
125 | ```yaml
126 | Type: wsbMappedFolder[]
127 | Parameter Sets: (All)
128 | Aliases:
129 |
130 | Required: False
131 | Position: Named
132 | Default value: None
133 | Accept pipeline input: True (ByPropertyName)
134 | Accept wildcard characters: False
135 | ```
136 |
137 | ### -MemoryInMB
138 |
139 | ```yaml
140 | Type: String
141 | Parameter Sets: (All)
142 | Aliases:
143 |
144 | Required: False
145 | Position: Named
146 | Default value: 4096
147 | Accept pipeline input: True (ByPropertyName)
148 | Accept wildcard characters: False
149 | ```
150 |
151 | ### -Metadata
152 |
153 | A set of metadata values. This will typically be configured by default.
154 |
155 | ```yaml
156 | Type: wsbMetadata
157 | Parameter Sets: meta
158 | Aliases:
159 |
160 | Required: False
161 | Position: Named
162 | Default value: None
163 | Accept pipeline input: False
164 | Accept wildcard characters: False
165 | ```
166 |
167 | ### -Name
168 |
169 | Give the configuration a name
170 |
171 | ```yaml
172 | Type: String
173 | Parameter Sets: name
174 | Aliases:
175 |
176 | Required: True
177 | Position: Named
178 | Default value: None
179 | Accept pipeline input: False
180 | Accept wildcard characters: False
181 | ```
182 |
183 | ### -Networking
184 |
185 | ```yaml
186 | Type: String
187 | Parameter Sets: (All)
188 | Aliases:
189 | Accepted values: Default, Disable
190 |
191 | Required: False
192 | Position: Named
193 | Default value: Default
194 | Accept pipeline input: True (ByPropertyName)
195 | Accept wildcard characters: False
196 | ```
197 |
198 | ### -PrinterRedirection
199 |
200 | ```yaml
201 | Type: String
202 | Parameter Sets: (All)
203 | Aliases:
204 | Accepted values: Default, Enable, Disable
205 |
206 | Required: False
207 | Position: Named
208 | Default value: Default
209 | Accept pipeline input: True (ByPropertyName)
210 | Accept wildcard characters: False
211 | ```
212 |
213 | ### -ProtectedClient
214 |
215 | ```yaml
216 | Type: String
217 | Parameter Sets: (All)
218 | Aliases:
219 | Accepted values: Default, Enable, Disable
220 |
221 | Required: False
222 | Position: Named
223 | Default value: Default
224 | Accept pipeline input: True (ByPropertyName)
225 | Accept wildcard characters: False
226 | ```
227 |
228 | ### -VideoInput
229 |
230 | ```yaml
231 | Type: String
232 | Parameter Sets: (All)
233 | Aliases:
234 | Accepted values: Default, Enable, Disable
235 |
236 | Required: False
237 | Position: Named
238 | Default value: Default
239 | Accept pipeline input: True (ByPropertyName)
240 | Accept wildcard characters: False
241 | ```
242 |
243 | ### -vGPU
244 |
245 | ```yaml
246 | Type: String
247 | Parameter Sets: (All)
248 | Aliases:
249 | Accepted values: Default, Enable, Disable
250 |
251 | Required: False
252 | Position: Named
253 | Default value: Default
254 | Accept pipeline input: True (ByPropertyName)
255 | Accept wildcard characters: False
256 | ```
257 |
258 | ### CommonParameters
259 |
260 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
261 |
262 | ## INPUTS
263 |
264 | ### System.String
265 |
266 | ### System.Object
267 |
268 | ### wsbMappedFolder[]
269 |
270 | ## OUTPUTS
271 |
272 | ### wsbConfiguration
273 |
274 | ## NOTES
275 |
276 | Learn more about PowerShell: http://jdhitsolutions.com/blog/essential-powershell-resources/
277 |
278 | ## RELATED LINKS
279 |
280 | [New-WsbMappedFolder](New-WsbMappedFolder.md)
281 |
282 | [Export-WsbConfiguration](Export-WsbConfiguration.md)
283 |
--------------------------------------------------------------------------------
/docs/New-WsbMappedFolder.md:
--------------------------------------------------------------------------------
1 | ---
2 | external help file: WindowsSandboxTools-help.xml
3 | Module Name: WindowsSandboxTools
4 | online version: https://bit.ly/3PkPqUH
5 | schema: 2.0.0
6 | ---
7 |
8 | # New-WsbMappedFolder
9 |
10 | ## SYNOPSIS
11 |
12 | Create a mapped folder object.
13 |
14 | ## SYNTAX
15 |
16 | ```yaml
17 | New-WsbMappedFolder [-HostFolder] [-SandboxFolder] [-ReadOnly] []
18 | ```
19 |
20 | ## DESCRIPTION
21 |
22 | You this folder to create a new mapped folder object. You can use this when creating a new Windows sandbox configuration. The sandbox will only have a C: drive.
23 |
24 | ## EXAMPLES
25 |
26 | ### Example 1
27 |
28 | ```powershell
29 | PS C:\> $map = New-WsbMappedFolder -HostFolder c:\work -SandboxFolder c:\work
30 | PS C:\> New-WsbConfiguration -Name work -MappedFolder $map -Description "Work sandbox"
31 | ```
32 |
33 | Create a shared folder with write access and then use that object in a new configuration.
34 |
35 | ## PARAMETERS
36 |
37 | ### -HostFolder
38 |
39 | Specify the path to the local folder you want to map. This folder must already exist.
40 |
41 | ```yaml
42 | Type: String
43 | Parameter Sets: (All)
44 | Aliases:
45 |
46 | Required: True
47 | Position: 0
48 | Default value: None
49 | Accept pipeline input: True (ByPropertyName)
50 | Accept wildcard characters: False
51 | ```
52 |
53 | ### -ReadOnly
54 |
55 | Specify if you want the mapping to be Read-Only.
56 |
57 | ```yaml
58 | Type: SwitchParameter
59 | Parameter Sets: (All)
60 | Aliases:
61 |
62 | Required: False
63 | Position: Named
64 | Default value: None
65 | Accept pipeline input: True (ByPropertyName)
66 | Accept wildcard characters: False
67 | ```
68 |
69 | ### -SandboxFolder
70 |
71 | Specify the mapped folder for the Windows Sandbox.
72 | It must start with C:\
73 |
74 | ```yaml
75 | Type: String
76 | Parameter Sets: (All)
77 | Aliases:
78 |
79 | Required: True
80 | Position: 1
81 | Default value: None
82 | Accept pipeline input: True (ByPropertyName)
83 | Accept wildcard characters: False
84 | ```
85 |
86 | ### CommonParameters
87 |
88 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
89 |
90 | ## INPUTS
91 |
92 | ### System.String
93 |
94 | ## OUTPUTS
95 |
96 | ### wsbMappedFolder
97 |
98 | ## NOTES
99 |
100 | Learn more about PowerShell: http://jdhitsolutions.com/blog/essential-powershell-resources/
101 |
102 | ## RELATED LINKS
103 |
104 | [New-WsbConfiguration](New-WsbConfiguration.md)
105 |
--------------------------------------------------------------------------------
/docs/Start-WindowsSandbox.md:
--------------------------------------------------------------------------------
1 | ---
2 | external help file: WindowsSandboxTools-help.xml
3 | Module Name: WindowsSandboxTools
4 | online version: https://bit.ly/42Wde4i
5 | schema: 2.0.0
6 | ---
7 |
8 | # Start-WindowsSandbox
9 |
10 | ## SYNOPSIS
11 |
12 | Start a Windows sandbox configuration.
13 |
14 | ## SYNTAX
15 |
16 | ### config (Default)
17 |
18 | ```yaml
19 | Start-WindowsSandbox [-Configuration] [-WindowSize ] [-WhatIf] [-Confirm] []
20 | ```
21 |
22 | ### normal
23 |
24 | ```yaml
25 | Start-WindowsSandbox [-NoSetup] [-WindowSize ] [-WhatIf] [-Confirm] []
26 | ```
27 |
28 | ## DESCRIPTION
29 |
30 | Use this command, or its alias wsb, to launch Windows Sandbox. You can specify a configuration or use -NoSetup to run the default sandbox.
31 |
32 | ## EXAMPLES
33 |
34 | ### Example 1
35 |
36 | ```powershell
37 | PS C:\> Start-WindowsSandbox -noSetup -windowsize 1024,768
38 | ```
39 |
40 | This will launch the default Windows sandobx and attempt to configure the screen resolution to 1024x768.
41 |
42 | ### Example 2
43 |
44 | ```powershell
45 | PS C:\> Start-WindowsSandbox $wsbconfigPath\presentation.wsb
46 | ```
47 |
48 | ## PARAMETERS
49 |
50 | ### -Configuration
51 |
52 | Specify the path to a wsb file. The command will autocomplete using the $wsbConfigPath variable.
53 |
54 | ```yaml
55 | Type: String
56 | Parameter Sets: config
57 | Aliases:
58 |
59 | Required: True
60 | Position: 0
61 | Default value: None
62 | Accept pipeline input: False
63 | Accept wildcard characters: False
64 | ```
65 |
66 | ### -Confirm
67 |
68 | Prompts you for confirmation before running the cmdlet.
69 |
70 | ```yaml
71 | Type: SwitchParameter
72 | Parameter Sets: (All)
73 | Aliases: cf
74 |
75 | Required: False
76 | Position: Named
77 | Default value: None
78 | Accept pipeline input: False
79 | Accept wildcard characters: False
80 | ```
81 |
82 | ### -NoSetup
83 |
84 | Start with no customizations.
85 |
86 | ```yaml
87 | Type: SwitchParameter
88 | Parameter Sets: normal
89 | Aliases:
90 |
91 | Required: False
92 | Position: Named
93 | Default value: None
94 | Accept pipeline input: False
95 | Accept wildcard characters: False
96 | ```
97 |
98 | ### -WhatIf
99 |
100 | Shows what would happen if the cmdlet runs.
101 | The cmdlet is not run.
102 |
103 | ```yaml
104 | Type: SwitchParameter
105 | Parameter Sets: (All)
106 | Aliases: wi
107 |
108 | Required: False
109 | Position: Named
110 | Default value: None
111 | Accept pipeline input: False
112 | Accept wildcard characters: False
113 | ```
114 |
115 | ### -WindowSize
116 |
117 | Specify desktop resolutions as an array like 1280,720.
118 | The default is 1920,1080. This feature may not be 100% correct and should be considered an experimental feature.
119 |
120 | ```yaml
121 | Type: Int32[]
122 | Parameter Sets: (All)
123 | Aliases:
124 |
125 | Required: False
126 | Position: Named
127 | Default value: 1920,1080
128 | Accept pipeline input: False
129 | Accept wildcard characters: False
130 | ```
131 |
132 | ### CommonParameters
133 |
134 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
135 |
136 | ## INPUTS
137 |
138 | ### None
139 |
140 | ## OUTPUTS
141 |
142 | ### none
143 |
144 | ## NOTES
145 |
146 | Learn more about PowerShell: http://jdhitsolutions.com/blog/essential-powershell-resources/
147 |
148 | ## RELATED LINKS
149 |
150 | [Get-WsbConfiguration](Get-WsbConfiguration.md)
151 |
--------------------------------------------------------------------------------
/en-us/WindowsSandboxTools-help.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Export-WsbConfiguration
6 | Export
7 | WsbConfiguration
8 |
9 | Export a WSB configuration to an XML file.
10 |
11 |
12 |
13 | This command will take an existing Windows Sandbox Configuration object and export it to an XML file.
14 |
15 |
16 |
17 | Export-WsbConfiguration
18 |
19 | Configuration
20 |
21 | Specify a wsbConfiguration object.
22 |
23 | wsbConfiguration
24 |
25 | wsbConfiguration
26 |
27 |
28 | None
29 |
30 |
31 | Confirm
32 |
33 | Prompts you for confirmation before running the cmdlet.
34 |
35 |
36 | SwitchParameter
37 |
38 |
39 | False
40 |
41 |
42 | NoClobber
43 |
44 | Don't overwrite an existing file.
45 |
46 |
47 | SwitchParameter
48 |
49 |
50 | False
51 |
52 |
53 | Path
54 |
55 | Specify the path and filename. It must end in .wsb
56 |
57 | String
58 |
59 | String
60 |
61 |
62 | None
63 |
64 |
65 | WhatIf
66 |
67 | Shows what would happen if the cmdlet runs. The cmdlet is not run.
68 |
69 |
70 | SwitchParameter
71 |
72 |
73 | False
74 |
75 |
76 |
77 |
78 |
79 | Configuration
80 |
81 | Specify a wsbConfiguration object.
82 |
83 | wsbConfiguration
84 |
85 | wsbConfiguration
86 |
87 |
88 | None
89 |
90 |
91 | Confirm
92 |
93 | Prompts you for confirmation before running the cmdlet.
94 |
95 | SwitchParameter
96 |
97 | SwitchParameter
98 |
99 |
100 | False
101 |
102 |
103 | NoClobber
104 |
105 | Don't overwrite an existing file.
106 |
107 | SwitchParameter
108 |
109 | SwitchParameter
110 |
111 |
112 | False
113 |
114 |
115 | Path
116 |
117 | Specify the path and filename. It must end in .wsb
118 |
119 | String
120 |
121 | String
122 |
123 |
124 | None
125 |
126 |
127 | WhatIf
128 |
129 | Shows what would happen if the cmdlet runs. The cmdlet is not run.
130 |
131 | SwitchParameter
132 |
133 | SwitchParameter
134 |
135 |
136 | False
137 |
138 |
139 |
140 |
141 |
142 | wsbConfiguration
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 | System.IO.FileInfo
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 | Learn more about PowerShell: http://jdhitsolutions.com/blog/essential-powershell-resources/
162 |
163 |
164 |
165 |
166 | -------------------------- Example 1 --------------------------
167 | PS C:\> New-WsbConfiguration -Name demo -LogonCommand C:\scripts\wsbscripts\sandbox-basic.cmd -MemoryInMB (4096*2) -MappedFolder (New-WsbMappedFolder -HostFolder c:\scratch -SandboxFolder c:\junk) -Description "My test WSB configuration" | Export-WsbConfiguration -Path c:\scratch\scratch.wsb
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 | Online Version:
176 | https://bit.ly/3PkXMvl
177 |
178 |
179 | New-WsbConfiguration
180 |
181 |
182 |
183 |
184 |
185 |
186 | Get-WsbConfiguration
187 | Get
188 | WsbConfiguration
189 |
190 | Get a Windows Sandbox configuration.
191 |
192 |
193 |
194 | This command will give you information about a sandbox configuration.
195 |
196 |
197 |
198 | Get-WsbConfiguration
199 |
200 | Path
201 |
202 | Specify the path to the .wsb file. The command will autocomplete to the $wsbConfigPath variable.
203 |
204 | String
205 |
206 | String
207 |
208 |
209 | None
210 |
211 |
212 | MetadataOnly
213 |
214 | Only display metadata information.
215 |
216 |
217 | SwitchParameter
218 |
219 |
220 | False
221 |
222 |
223 |
224 |
225 |
226 | MetadataOnly
227 |
228 | Only display metadata information.
229 |
230 | SwitchParameter
231 |
232 | SwitchParameter
233 |
234 |
235 | False
236 |
237 |
238 | Path
239 |
240 | Specify the path to the .wsb file. The command will autocomplete to the $wsbConfigPath variable.
241 |
242 | String
243 |
244 | String
245 |
246 |
247 | None
248 |
249 |
250 |
251 |
252 |
253 | None
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 | wsbConfiguration
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 | Learn more about PowerShell: http://jdhitsolutions.com/blog/essential-powershell-resources/
273 |
274 |
275 |
276 |
277 | -------------------------- Example 1 --------------------------
278 | PS C:\> Get-WsbConfiguration C:\Scripts\WindowsSandboxTools\wsbConfig\dev.wsb
279 |
280 | Name: C:\scripts\wsbconfig\dev.wsb
281 |
282 | vGPU : Enable
283 | MemoryInMB : 8192
284 | AudioInput : Disable
285 | VideoInput : Default
286 | ClipboardRedirection : Default
287 | PrinterRedirection : Default
288 | Networking : Default
289 | ProtectedClient : Disable
290 | LogonCommand : C:\scripts\wsbScripts\sandbox-setup.cmd
291 | MappedFolders : C:\scripts -> C:\scripts [RO:False]
292 | C:\Pluralsight -> C:\Pluralsight [RO:True]
293 |
294 |
295 |
296 |
297 |
298 | -------------------------- Example 2 --------------------------
299 | PS C:\> Get-WsbConfiguration C:\Scripts\WindowsSandboxTools\wsbConfig\dev.wsb -MetadataOnly
300 |
301 | Author Name Description Updated
302 | ------ ---- ----------- -------
303 | Jeff C:\scripts\wsbconfig\dev.wsb A test wsb file 12/10/2020 8:50:03 AM
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 | Online Version:
312 | https://bit.ly/44aWC9X
313 |
314 |
315 | New-WsbConfiguration
316 |
317 |
318 |
319 |
320 |
321 |
322 | New-WsbConfiguration
323 | New
324 | WsbConfiguration
325 |
326 | Create a new Windows Sandbox configuration.
327 |
328 |
329 |
330 | This command will create a new Wsbconfiguration object. Use Export-Wsbconfiguration to save it to disk.
331 |
332 |
333 |
334 | New-WsbConfiguration
335 |
336 | AudioInput
337 |
338 |
339 |
340 |
341 | Default
342 | Enable
343 | Disable
344 |
345 | String
346 |
347 | String
348 |
349 |
350 | Default
351 |
352 |
353 | Author
354 |
355 | Who is the author?
356 |
357 | String
358 |
359 | String
360 |
361 |
362 | current user
363 |
364 |
365 | ClipboardRedirection
366 |
367 |
368 |
369 |
370 | Default
371 | Disable
372 |
373 | String
374 |
375 | String
376 |
377 |
378 | Default
379 |
380 |
381 | Description
382 |
383 | Provide a description for this configuration.
384 |
385 | String
386 |
387 | String
388 |
389 |
390 | None
391 |
392 |
393 | LogonCommand
394 |
395 | The path and file are relative to the Windows Sandbox configuration.
396 |
397 | Object
398 |
399 | Object
400 |
401 |
402 | None
403 |
404 |
405 | MappedFolder
406 |
407 | Specify a mapped folder object.
408 |
409 | wsbMappedFolder[]
410 |
411 | wsbMappedFolder[]
412 |
413 |
414 | None
415 |
416 |
417 | MemoryInMB
418 |
419 |
420 |
421 | String
422 |
423 | String
424 |
425 |
426 | 4096
427 |
428 |
429 | Name
430 |
431 | Give the configuration a name
432 |
433 | String
434 |
435 | String
436 |
437 |
438 | None
439 |
440 |
441 | Networking
442 |
443 |
444 |
445 |
446 | Default
447 | Disable
448 |
449 | String
450 |
451 | String
452 |
453 |
454 | Default
455 |
456 |
457 | PrinterRedirection
458 |
459 |
460 |
461 |
462 | Default
463 | Enable
464 | Disable
465 |
466 | String
467 |
468 | String
469 |
470 |
471 | Default
472 |
473 |
474 | ProtectedClient
475 |
476 |
477 |
478 |
479 | Default
480 | Enable
481 | Disable
482 |
483 | String
484 |
485 | String
486 |
487 |
488 | Default
489 |
490 |
491 | VideoInput
492 |
493 |
494 |
495 |
496 | Default
497 | Enable
498 | Disable
499 |
500 | String
501 |
502 | String
503 |
504 |
505 | Default
506 |
507 |
508 | vGPU
509 |
510 |
511 |
512 |
513 | Default
514 | Enable
515 | Disable
516 |
517 | String
518 |
519 | String
520 |
521 |
522 | Default
523 |
524 |
525 |
526 | New-WsbConfiguration
527 |
528 | AudioInput
529 |
530 |
531 |
532 |
533 | Default
534 | Enable
535 | Disable
536 |
537 | String
538 |
539 | String
540 |
541 |
542 | Default
543 |
544 |
545 | ClipboardRedirection
546 |
547 |
548 |
549 |
550 | Default
551 | Disable
552 |
553 | String
554 |
555 | String
556 |
557 |
558 | Default
559 |
560 |
561 | LogonCommand
562 |
563 | The path and file are relative to the Windows Sandbox configuration.
564 |
565 | Object
566 |
567 | Object
568 |
569 |
570 | None
571 |
572 |
573 | MappedFolder
574 |
575 | Specify a mapped folder object.
576 |
577 | wsbMappedFolder[]
578 |
579 | wsbMappedFolder[]
580 |
581 |
582 | None
583 |
584 |
585 | MemoryInMB
586 |
587 |
588 |
589 | String
590 |
591 | String
592 |
593 |
594 | 4096
595 |
596 |
597 | Metadata
598 |
599 | A set of metadata values. This will typically be configured by default.
600 |
601 | wsbMetadata
602 |
603 | wsbMetadata
604 |
605 |
606 | None
607 |
608 |
609 | Networking
610 |
611 |
612 |
613 |
614 | Default
615 | Disable
616 |
617 | String
618 |
619 | String
620 |
621 |
622 | Default
623 |
624 |
625 | PrinterRedirection
626 |
627 |
628 |
629 |
630 | Default
631 | Enable
632 | Disable
633 |
634 | String
635 |
636 | String
637 |
638 |
639 | Default
640 |
641 |
642 | ProtectedClient
643 |
644 |
645 |
646 |
647 | Default
648 | Enable
649 | Disable
650 |
651 | String
652 |
653 | String
654 |
655 |
656 | Default
657 |
658 |
659 | VideoInput
660 |
661 |
662 |
663 |
664 | Default
665 | Enable
666 | Disable
667 |
668 | String
669 |
670 | String
671 |
672 |
673 | Default
674 |
675 |
676 | vGPU
677 |
678 |
679 |
680 |
681 | Default
682 | Enable
683 | Disable
684 |
685 | String
686 |
687 | String
688 |
689 |
690 | Default
691 |
692 |
693 |
694 |
695 |
696 | AudioInput
697 |
698 |
699 |
700 | String
701 |
702 | String
703 |
704 |
705 | Default
706 |
707 |
708 | Author
709 |
710 | Who is the author?
711 |
712 | String
713 |
714 | String
715 |
716 |
717 | current user
718 |
719 |
720 | ClipboardRedirection
721 |
722 |
723 |
724 | String
725 |
726 | String
727 |
728 |
729 | Default
730 |
731 |
732 | Description
733 |
734 | Provide a description for this configuration.
735 |
736 | String
737 |
738 | String
739 |
740 |
741 | None
742 |
743 |
744 | LogonCommand
745 |
746 | The path and file are relative to the Windows Sandbox configuration.
747 |
748 | Object
749 |
750 | Object
751 |
752 |
753 | None
754 |
755 |
756 | MappedFolder
757 |
758 | Specify a mapped folder object.
759 |
760 | wsbMappedFolder[]
761 |
762 | wsbMappedFolder[]
763 |
764 |
765 | None
766 |
767 |
768 | MemoryInMB
769 |
770 |
771 |
772 | String
773 |
774 | String
775 |
776 |
777 | 4096
778 |
779 |
780 | Metadata
781 |
782 | A set of metadata values. This will typically be configured by default.
783 |
784 | wsbMetadata
785 |
786 | wsbMetadata
787 |
788 |
789 | None
790 |
791 |
792 | Name
793 |
794 | Give the configuration a name
795 |
796 | String
797 |
798 | String
799 |
800 |
801 | None
802 |
803 |
804 | Networking
805 |
806 |
807 |
808 | String
809 |
810 | String
811 |
812 |
813 | Default
814 |
815 |
816 | PrinterRedirection
817 |
818 |
819 |
820 | String
821 |
822 | String
823 |
824 |
825 | Default
826 |
827 |
828 | ProtectedClient
829 |
830 |
831 |
832 | String
833 |
834 | String
835 |
836 |
837 | Default
838 |
839 |
840 | VideoInput
841 |
842 |
843 |
844 | String
845 |
846 | String
847 |
848 |
849 | Default
850 |
851 |
852 | vGPU
853 |
854 |
855 |
856 | String
857 |
858 | String
859 |
860 |
861 | Default
862 |
863 |
864 |
865 |
866 |
867 | System.String
868 |
869 |
870 |
871 |
872 |
873 |
874 |
875 | System.Object
876 |
877 |
878 |
879 |
880 |
881 |
882 |
883 | wsbMappedFolder[]
884 |
885 |
886 |
887 |
888 |
889 |
890 |
891 |
892 |
893 | wsbConfiguration
894 |
895 |
896 |
897 |
898 |
899 |
900 |
901 |
902 | Learn more about PowerShell: http://jdhitsolutions.com/blog/essential-powershell-resources/
903 |
904 |
905 |
906 |
907 | -------------------------- Example 1 --------------------------
908 | PS C:\> $new = New-WsbConfiguration -Name demo -LogonCommand C:\scripts\wsbscripts\sandbox-basic.cmd -MemoryInMB (4096*2) -MappedFolder (New-WsbMappedFolder -HostFolder c:\scratch -SandboxFolder c:\junk) -description "My scratch configuration"
909 |
910 |
911 |
912 |
913 |
914 |
915 |
916 | Online Version:
917 | https://bit.ly/3qSqCJA
918 |
919 |
920 | New-WsbMappedFolder
921 |
922 |
923 |
924 | Export-WsbConfiguration
925 |
926 |
927 |
928 |
929 |
930 |
931 | New-WsbMappedFolder
932 | New
933 | WsbMappedFolder
934 |
935 | Create a mapped folder object.
936 |
937 |
938 |
939 | You this folder to create a new mapped folder object. You can use this when creating a new Windows sandbox configuration. The sandbox will only have a C: drive.
940 |
941 |
942 |
943 | New-WsbMappedFolder
944 |
945 | HostFolder
946 |
947 | Specify the path to the local folder you want to map. This folder must already exist.
948 |
949 | String
950 |
951 | String
952 |
953 |
954 | None
955 |
956 |
957 | SandboxFolder
958 |
959 | Specify the mapped folder for the Windows Sandbox. It must start with C:\
960 |
961 | String
962 |
963 | String
964 |
965 |
966 | None
967 |
968 |
969 | ReadOnly
970 |
971 | Specify if you want the mapping to be Read-Only.
972 |
973 |
974 | SwitchParameter
975 |
976 |
977 | False
978 |
979 |
980 |
981 |
982 |
983 | HostFolder
984 |
985 | Specify the path to the local folder you want to map. This folder must already exist.
986 |
987 | String
988 |
989 | String
990 |
991 |
992 | None
993 |
994 |
995 | ReadOnly
996 |
997 | Specify if you want the mapping to be Read-Only.
998 |
999 | SwitchParameter
1000 |
1001 | SwitchParameter
1002 |
1003 |
1004 | False
1005 |
1006 |
1007 | SandboxFolder
1008 |
1009 | Specify the mapped folder for the Windows Sandbox. It must start with C:\
1010 |
1011 | String
1012 |
1013 | String
1014 |
1015 |
1016 | None
1017 |
1018 |
1019 |
1020 |
1021 |
1022 | System.String
1023 |
1024 |
1025 |
1026 |
1027 |
1028 |
1029 |
1030 |
1031 |
1032 | wsbMappedFolder
1033 |
1034 |
1035 |
1036 |
1037 |
1038 |
1039 |
1040 |
1041 | Learn more about PowerShell: http://jdhitsolutions.com/blog/essential-powershell-resources/
1042 |
1043 |
1044 |
1045 |
1046 | -------------------------- Example 1 --------------------------
1047 | PS C:\> $map = New-WsbMappedFolder -HostFolder c:\work -SandboxFolder c:\work
1048 | PS C:\> New-WsbConfiguration -Name work -MappedFolder $map -Description "Work sandbox"
1049 |
1050 | Create a shared folder with write access and then use that object in a new configuration.
1051 |
1052 |
1053 |
1054 |
1055 |
1056 | Online Version:
1057 | https://bit.ly/3PkPqUH
1058 |
1059 |
1060 | New-WsbConfiguration
1061 |
1062 |
1063 |
1064 |
1065 |
1066 |
1067 | Start-WindowsSandbox
1068 | Start
1069 | WindowsSandbox
1070 |
1071 | Start a Windows sandbox configuration.
1072 |
1073 |
1074 |
1075 | Use this command, or its alias wsb, to launch Windows Sandbox. You can specify a configuration or use -NoSetup to run the default sandbox.
1076 |
1077 |
1078 |
1079 | Start-WindowsSandbox
1080 |
1081 | Configuration
1082 |
1083 | Specify the path to a wsb file. The command will autocomplete using the $wsbConfigPath variable.
1084 |
1085 | String
1086 |
1087 | String
1088 |
1089 |
1090 | None
1091 |
1092 |
1093 | Confirm
1094 |
1095 | Prompts you for confirmation before running the cmdlet.
1096 |
1097 |
1098 | SwitchParameter
1099 |
1100 |
1101 | False
1102 |
1103 |
1104 | WhatIf
1105 |
1106 | Shows what would happen if the cmdlet runs. The cmdlet is not run.
1107 |
1108 |
1109 | SwitchParameter
1110 |
1111 |
1112 | False
1113 |
1114 |
1115 | WindowSize
1116 |
1117 | Specify desktop resolutions as an array like 1280,720. The default is 1920,1080. This feature may not be 100% correct and should be considered an experimental feature.
1118 |
1119 | Int32[]
1120 |
1121 | Int32[]
1122 |
1123 |
1124 | 1920,1080
1125 |
1126 |
1127 |
1128 | Start-WindowsSandbox
1129 |
1130 | Confirm
1131 |
1132 | Prompts you for confirmation before running the cmdlet.
1133 |
1134 |
1135 | SwitchParameter
1136 |
1137 |
1138 | False
1139 |
1140 |
1141 | NoSetup
1142 |
1143 | Start with no customizations.
1144 |
1145 |
1146 | SwitchParameter
1147 |
1148 |
1149 | False
1150 |
1151 |
1152 | WhatIf
1153 |
1154 | Shows what would happen if the cmdlet runs. The cmdlet is not run.
1155 |
1156 |
1157 | SwitchParameter
1158 |
1159 |
1160 | False
1161 |
1162 |
1163 | WindowSize
1164 |
1165 | Specify desktop resolutions as an array like 1280,720. The default is 1920,1080. This feature may not be 100% correct and should be considered an experimental feature.
1166 |
1167 | Int32[]
1168 |
1169 | Int32[]
1170 |
1171 |
1172 | 1920,1080
1173 |
1174 |
1175 |
1176 |
1177 |
1178 | Configuration
1179 |
1180 | Specify the path to a wsb file. The command will autocomplete using the $wsbConfigPath variable.
1181 |
1182 | String
1183 |
1184 | String
1185 |
1186 |
1187 | None
1188 |
1189 |
1190 | Confirm
1191 |
1192 | Prompts you for confirmation before running the cmdlet.
1193 |
1194 | SwitchParameter
1195 |
1196 | SwitchParameter
1197 |
1198 |
1199 | False
1200 |
1201 |
1202 | NoSetup
1203 |
1204 | Start with no customizations.
1205 |
1206 | SwitchParameter
1207 |
1208 | SwitchParameter
1209 |
1210 |
1211 | False
1212 |
1213 |
1214 | WhatIf
1215 |
1216 | Shows what would happen if the cmdlet runs. The cmdlet is not run.
1217 |
1218 | SwitchParameter
1219 |
1220 | SwitchParameter
1221 |
1222 |
1223 | False
1224 |
1225 |
1226 | WindowSize
1227 |
1228 | Specify desktop resolutions as an array like 1280,720. The default is 1920,1080. This feature may not be 100% correct and should be considered an experimental feature.
1229 |
1230 | Int32[]
1231 |
1232 | Int32[]
1233 |
1234 |
1235 | 1920,1080
1236 |
1237 |
1238 |
1239 |
1240 |
1241 | None
1242 |
1243 |
1244 |
1245 |
1246 |
1247 |
1248 |
1249 |
1250 |
1251 | none
1252 |
1253 |
1254 |
1255 |
1256 |
1257 |
1258 |
1259 |
1260 | Learn more about PowerShell: http://jdhitsolutions.com/blog/essential-powershell-resources/
1261 |
1262 |
1263 |
1264 |
1265 | -------------------------- Example 1 --------------------------
1266 | PS C:\> Start-WindowsSandbox -noSetup -windowsize 1024,768
1267 |
1268 | This will launch the default Windows sandobx and attempt to configure the screen resolution to 1024x768.
1269 |
1270 |
1271 |
1272 | -------------------------- Example 2 --------------------------
1273 | PS C:\> Start-WindowsSandbox $wsbconfigPath\presentation.wsb
1274 |
1275 |
1276 |
1277 |
1278 |
1279 |
1280 |
1281 | Online Version:
1282 | https://bit.ly/42Wde4i
1283 |
1284 |
1285 | Get-WsbConfiguration
1286 |
1287 |
1288 |
1289 |
1290 |
--------------------------------------------------------------------------------
/formats/wsbConfiguration.format.ps1xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 | default
10 |
11 | wsbConfiguration
12 |
13 |
14 |
22 | $_.metadata.Name
23 | Name
24 |
25 |
26 |
27 |
28 |
29 |
33 |
34 | vGPU
35 | vGPU
36 |
37 |
38 | MemoryInMB
39 | MemoryInMB
40 |
41 |
42 | AudioInput
43 | AudioInput
44 |
45 |
46 | VideoInput
47 | VideoInput
48 |
49 |
50 | ClipboardRedirection
51 | ClipboardRedirection
52 |
53 |
54 | PrinterRedirection
55 | PrinterRedirection
56 |
57 |
58 | Networking
59 | Networking
60 |
61 |
62 | ProtectedClient
63 | ProtectedClient
64 |
65 |
66 | LogonCommand
67 | LogonCommand
68 |
69 |
70 | MappedFolders
71 |
72 | $mf = @()
73 | foreach ($f in $_.mappedfolder) {
74 | $mf+= "{0} -> {1} [RO:{2}]" -f $f.hostfolder,$f.sandboxfolder,$f.readonly
75 | }
76 | $mf -join "`n"
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/functions/Export-WsbConfiguration.ps1:
--------------------------------------------------------------------------------
1 | function Export-WsbConfiguration {
2 | [CmdletBinding(SupportsShouldProcess)]
3 | [OutputType([System.io.fileInfo])]
4 | param (
5 | [Parameter(Mandatory, Position = 0, ValueFromPipeline, HelpMessage = "Specify a wsbConfiguration object.")]
6 | [ValidateNotNullOrEmpty()]
7 | [wsbConfiguration]$Configuration,
8 | [Parameter(Mandatory, HelpMessage = "Specify the path and filename. It must end in .wsb")]
9 | [ValidatePattern("\.wsb$")]
10 | #verify the parent path exists
11 | [ValidateScript( { Test-Path $(Split-Path $_ -Parent) })]
12 | [String]$Path,
13 | [Parameter(HelpMessage = "Don't overwrite an existing file")]
14 | [Switch]$NoClobber
15 | )
16 | Begin {
17 | Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN] Starting $($MyInvocation.MyCommand)"
18 | <#
19 | Convert the path to a valid FileSystem path. Normally, I would use Convert-Path
20 | but it will fail if the file doesn't exist. Instead, I'll split the path, convert
21 | the root and recreate it.
22 | #>
23 | $parent = Convert-Path (Split-Path -Path $Path -Parent)
24 | $leaf = Split-Path -Path $Path -Leaf
25 | $cPath = Join-Path -Path $parent -ChildPath $leaf
26 | } #begin
27 | Process {
28 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Creating an XML document"
29 | $xml = New-Object System.Xml.XmlDocument
30 | $config = $xml.CreateElement("element", "Configuration", "")
31 |
32 | #add my custom metadata
33 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Inserting metadata"
34 | $meta = $xml.CreateElement("element", "Metadata", "")
35 | $metaprops = "Name", "Author", "Description", "Updated"
36 | foreach ($prop in $metaprops) {
37 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] ..$prop = $($configuration.Metadata.$prop)"
38 | $item = $xml.CreateElement($prop)
39 | $item.set_innertext($configuration.Metadata.$prop)
40 | [void]$meta.AppendChild($item)
41 | }
42 | [void]$config.AppendChild($meta)
43 |
44 | #add primary properties
45 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Adding primary data"
46 | $mainprops = "vGPU", "MemoryInMB", "AudioInput", "VideoInput", "ClipboardRedirection", "PrinterRedirection",
47 | "Networking", "ProtectedClient"
48 | foreach ($prop in $mainprops) {
49 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] ..$prop = $($configuration.$prop)"
50 | $item = $xml.CreateElement($prop)
51 | $item.set_innertext($configuration.$prop)
52 | [void]$config.AppendChild($item)
53 | }
54 | if ($Configuration.LogonCommand) {
55 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Adding a logon command"
56 | $logon = $xml.CreateElement("element", "LogonCommand", "")
57 | $cmd = $xml.CreateElement("Command")
58 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] ..$($configuration.LogonCommand)"
59 | $cmd.set_innerText($configuration.LogonCommand)
60 | [void]$logon.AppendChild($cmd)
61 | [void]$config.AppendChild($logon)
62 | }
63 | if ($Configuration.MappedFolder) {
64 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Adding mapped folders"
65 | $mapped = $xml.CreateElement("element", "MappedFolders", "")
66 | foreach ($f in $Configuration.MappedFolder) {
67 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] $($f.HostFolder) -> $($f.SandboxFolder) [RO:$($f.ReadOnly)]"
68 | $mf = $xml.CreateElement("element", "MappedFolder", "")
69 | "HostFolder", "SandboxFolder", "ReadOnly" |
70 | ForEach-Object {
71 | $item = $xml.CreateElement($_)
72 | $item.set_innertext($f.$_)
73 | [void]$mf.AppendChild($item)
74 | }
75 | [void]$mapped.appendChild($mf)
76 | }
77 | [void]$config.AppendChild($mapped)
78 | }
79 |
80 | [void]$xml.AppendChild($config)
81 |
82 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Exporting configuration to $cPath"
83 | if ($PSCmdlet.ShouldProcess($cpath)) {
84 | if ((Test-Path -Path $cPath) -AND $NoClobber) {
85 | Write-Warning "A file exists at $cPath and NoClobber was specified."
86 | }
87 | else {
88 | $xml.Save($cPath)
89 | }
90 | } #WhatIf
91 |
92 | } #process
93 | End {
94 | Write-Verbose "[$((Get-Date).TimeOfDay) END ] Ending $($MyInvocation.MyCommand)"
95 | } #end
96 | }
97 |
--------------------------------------------------------------------------------
/functions/Get-WsbConfiguration.ps1:
--------------------------------------------------------------------------------
1 | Function Get-WsbConfiguration {
2 | [CmdletBinding()]
3 | [OutputType('wsbConfiguration')]
4 | Param(
5 | [Parameter(
6 | Position = 0,
7 | Mandatory,
8 | ValueFromPipeline,
9 | HelpMessage = 'Specify the path to the .wsb file.'
10 | )]
11 | [ValidatePattern('\.wsb$')]
12 | [ValidateScript( { Test-Path $_ })]
13 | [ArgumentCompleter( { if (Test-Path $global:wsbConfigPath) { (Get-ChildItem $Global:wsbConfigPath).FullName } })]
14 | [String]$Path,
15 |
16 | [Parameter(HelpMessage = 'Only display metadata information.')]
17 | [Switch]$MetadataOnly
18 | )
19 |
20 | Begin {
21 | Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Starting $($MyInvocation.MyCommand)"
22 | } #begin
23 | Process {
24 |
25 | $cPath = Convert-Path $Path
26 | Write-Verbose "Getting configuration from $cPath"
27 |
28 | [xml]$wsb = Get-Content -Path $cPath
29 |
30 | Write-Verbose 'Building property list'
31 | $properties = [System.Collections.Generic.List[object]]::new()
32 | $properties.AddRange($wsb.configuration.PSAdapted.PSObject.properties.name)
33 | if ($properties.Contains('LogonCommand')) {
34 | [void]($properties.Remove('LogonCommand'))
35 | $properties.Add(@{Name = 'LogonCommand'; Expression = { $wsb.configuration.logonCommand.Command } })
36 | }
37 | if ($properties.Contains('MappedFolders')) {
38 | [void]($properties.Remove('MappedFolders'))
39 | $properties.Add(@{Name = 'MappedFolder'; Expression = {
40 | $wsb.Configuration.MappedFolders.MappedFolder |
41 | Select-Object *folder, @{Name = 'ReadOnly'; Expression = { if ($_.ReadOnly -eq 'True') { $True } else { $False } } } |
42 | New-WsbMappedFolder | New-WsbMappedFolder }
43 | })
44 | }
45 |
46 | Write-Verbose 'Get metadata information'
47 | if ($wsb.configuration.metadata) {
48 | Write-Verbose 'Existing metadata found'
49 | $meta = [wsbMetadata]::new($wsb.Configuration.metadata.Name, $wsb.configuration.metadata.Description)
50 | $meta.updated = $wsb.configuration.metadata.updated
51 | $meta.author = $wsb.configuration.metadata.author
52 | }
53 | else {
54 | Write-Verbose 'Defining new metadata'
55 | $meta = [wsbMetadata]::new($cPath)
56 | $meta.updated = Get-Date
57 | }
58 |
59 | if ($MetadataOnly) {
60 | Write-Verbose 'Displaying metadata only'
61 | $meta
62 | }
63 | else {
64 | Write-Verbose 'Sending configuration to New-WsbConfiguration'
65 | $wsb.configuration | Select-Object -Property $properties | New-WsbConfiguration -metadata $meta
66 | Write-Verbose "Ending $($MyInvocation.MyCommand)"
67 | }
68 | } #process
69 | End {
70 | Write-Verbose "[$((Get-Date).TimeOfDay) END ] Ending $($MyInvocation.MyCommand)"
71 | } #end
72 | }
73 |
--------------------------------------------------------------------------------
/functions/New-WsbConfiguration.ps1:
--------------------------------------------------------------------------------
1 | Function New-WsbConfiguration {
2 | [CmdletBinding(DefaultParameterSetName = "name")]
3 | [OutputType("wsbConfiguration")]
4 | Param(
5 | [Parameter(ValueFromPipelineByPropertyName)]
6 | [ValidateSet("Default", "Enable", "Disable")]
7 | [String]$vGPU = "Default",
8 |
9 | [Parameter(ValueFromPipelineByPropertyName)]
10 | [ValidateScript( { $_ -ge 1024 })]
11 | [String]$MemoryInMB = 4096,
12 |
13 | [Parameter(ValueFromPipelineByPropertyName)]
14 | [ValidateSet("Default", "Enable", "Disable")]
15 | [String]$AudioInput = "Default",
16 |
17 | [Parameter(ValueFromPipelineByPropertyName)]
18 | [ValidateSet("Default", "Enable", "Disable")]
19 | [String]$VideoInput = "Default",
20 |
21 | [Parameter(ValueFromPipelineByPropertyName)]
22 | [ValidateSet("Default", "Disable")]
23 | [String]$ClipboardRedirection = "Default",
24 |
25 | [Parameter(ValueFromPipelineByPropertyName)]
26 | [ValidateSet("Default", "Enable", "Disable")]
27 | [String]$PrinterRedirection = "Default",
28 |
29 | [Parameter(ValueFromPipelineByPropertyName)]
30 | [ValidateSet("Default", "Disable")]
31 | [String]$Networking = "Default",
32 |
33 | [Parameter(ValueFromPipelineByPropertyName)]
34 | [ValidateSet("Default", "Enable", "Disable")]
35 | [String]$ProtectedClient = "Default",
36 |
37 | [Parameter(ValueFromPipelineByPropertyName, HelpMessage = "The path and file are relative to the Windows Sandbox")]
38 | [object]$LogonCommand,
39 |
40 | [Parameter(ValueFromPipelineByPropertyName)]
41 | [wsbMappedFolder[]]$MappedFolder,
42 |
43 | [Parameter(ParameterSetName = "meta")]
44 | [wsbMetadata]$Metadata,
45 |
46 | [parameter(Mandatory, ParameterSetName = "name", HelpMessage = "Give the configuration a name")]
47 | [String]$Name,
48 |
49 | [parameter(ParameterSetName = "name", HelpMessage = "Provide a description")]
50 | [String]$Description,
51 |
52 | [parameter(ParameterSetName = "name", HelpMessage = "Who is the author?")]
53 | [String]$Author = $env:USERNAME
54 | )
55 |
56 | Begin {
57 | Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN] Starting $($MyInvocation.MyCommand)"
58 | $new = [wsbConfiguration]::new()
59 | } #begin
60 | Process {
61 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Creating a configuration"
62 | Write-Verbose ($PSBoundParameters | Out-String)
63 |
64 | if ($logonCommand -is [String]) {
65 | $cmd = $LogonCommand
66 | }
67 | elseif ($logonCommand.Command) {
68 | $cmd = $logonCommand.Command
69 | }
70 | else {
71 | Write-Warning "No value detected for LogonCommand. This may be intentional on your part."
72 | $cmd = $Null
73 | }
74 |
75 | $new.vGPU = $vGPU
76 | $new.MemoryInMB = $MemoryInMB
77 | $new.AudioInput = $AudioInput
78 | $new.VideoInput = $VideoInput
79 | $new.ClipboardRedirection = $ClipboardRedirection
80 | $new.PrinterRedirection = $PrinterRedirection
81 | $new.Networking = $Networking
82 | $new.ProtectedClient = $ProtectedClient
83 | $new.LogonCommand = $cmd
84 | $new.MappedFolder = $MappedFolder
85 |
86 | if (-Not $metadata) {
87 | $metadata = [wsbMetadata]::new($Name, $Description)
88 | $metadata.author = $author
89 | $metadata.updated = Get-Date
90 | }
91 |
92 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Setting metadata"
93 | $new.metadata = $metadata
94 | $new
95 |
96 | } #process
97 | End {
98 | Write-Verbose "[$((Get-Date).TimeOfDay) END ] Ending $($MyInvocation.MyCommand)"
99 | } #end
100 | }
101 |
--------------------------------------------------------------------------------
/functions/New-WsbMappedFolder.ps1:
--------------------------------------------------------------------------------
1 | Function New-WsbMappedFolder {
2 | [CmdletBinding()]
3 | [OutputType("wsbMappedFolder")]
4 | Param(
5 | [Parameter(Position = 0, Mandatory, ValueFromPipelineByPropertyName, HelpMessage = "Specify the path to the local folder you want to map.")]
6 | [ValidateScript( { Test-Path $_ })]
7 | [String]$HostFolder,
8 |
9 | [Parameter(Position = 1, Mandatory, ValueFromPipelineByPropertyName, HelpMessage = "Specify the mapped folder for the Windows Sandbox. It must start with C:\")]
10 | [ValidateNotNullOrEmpty()]
11 | [ValidatePattern('^C:\\')]
12 | [String]$SandboxFolder,
13 |
14 | [Parameter(ValueFromPipelineByPropertyName, HelpMessage = "Specify if you want the mapping to be Read-Only.")]
15 | #[ValidateSet("True", "False")]
16 | [Switch]$ReadOnly
17 | )
18 |
19 | Begin {
20 | Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN] Starting $($MyInvocation.MyCommand)"
21 | } #begin
22 | Process {
23 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Processing"
24 |
25 | [wsbMappedFolder]::New($HostFolder, $SandboxFolder, $ReadOnly)
26 | } #process
27 | End {
28 | Write-Verbose "[$((Get-Date).TimeOfDay) END ] Ending $($MyInvocation.MyCommand)"
29 | } #end
30 | }
31 |
--------------------------------------------------------------------------------
/functions/Start-WindowsSandbox.ps1:
--------------------------------------------------------------------------------
1 | Function Start-WindowsSandbox {
2 | [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = "config")]
3 | [alias("wsb")]
4 | [OutputType("none")]
5 |
6 | Param(
7 | [Parameter(Position = 0, Mandatory, ParameterSetName = "config", HelpMessage = "Specify the path to a wsb file.")]
8 | [ValidateScript( { Test-Path $_ })]
9 | [ArgumentCompleter( { if (Test-Path $global:wsbConfigPath) { (Get-ChildItem $Global:wsbConfigPath).FullName } })]
10 | [String]$Configuration,
11 |
12 | [Parameter(ParameterSetName = "normal", HelpMessage = "Start with no customizations.")]
13 | [Switch]$NoSetup,
14 |
15 | [Parameter(HelpMessage = "Specify desktop resolutions as an array like 1280,720. The default is 1920,1080.")]
16 | [int[]]$WindowSize = @(1920, 1080)
17 | )
18 |
19 | Write-Verbose "[$((Get-Date).TimeOfDay)] Starting $($MyInvocation.MyCommand)"
20 |
21 | #test if Windows Sandbox is already running
22 | $test = Get-Process -ErrorAction SilentlyContinue -Name WindowsSandbox*
23 | if ($test) {
24 | Write-Warning "An instance of Windows Sandbox is already running."
25 | #bail out
26 | return
27 | }
28 | if ($NoSetup) {
29 | Write-Verbose "[$((Get-Date).TimeOfDay)] Launching default WindowsSandbox.exe"
30 | if ($PSCmdlet.ShouldProcess("default configuration", "Launch Windows Sandbox")) {
31 | Start-Process -FilePath $env:windir\system32\WindowsSandbox.exe
32 | }
33 | }
34 | else {
35 | Write-Verbose "[$((Get-Date).TimeOfDay)] Launching WindowsSandbox using configuration file $Configuration"
36 |
37 | #TODO - Parameterize this behavior
38 | #create a file watcher if calling a configuration that uses it
39 | if ($Configuration -match "WinSandBx|presentation") {
40 | Write-Verbose "[$((Get-Date).TimeOfDay)] Registering a temporary file system watcher"
41 | <#
42 | Some configurations will create "flag" file in a shared folder to indicate
43 | the setup and configuration is complete.
44 |
45 | RegisterWatcher is a private function in this module
46 | #>
47 | # TODO : pass arguments to RegisterWatcher from this function ?
48 | [void](Register-Watcher)
49 | }
50 |
51 | if ($PSCmdlet.ShouldProcess($Configuration, "Launch Windows Sandbox")) {
52 | Start-Process -FilePath $Configuration
53 | }
54 | }
55 |
56 | #WindowsSandbox.exe launches a child process, WindowsSandboxClient.
57 | #That is the process that needs to be minimized
58 | if ($PSCmdlet.ShouldProcess("WindowsSandboxClient", "Waiting for process")) {
59 |
60 | Write-Verbose "[$((Get-Date).TimeOfDay)] Waiting for child process WindowsSandboxClient"
61 | do {
62 | Start-Sleep -Seconds 1
63 | } Until (Get-Process -Name WindowsSandboxClient -ErrorAction SilentlyContinue)
64 |
65 | #give the process a chance to complete
66 | Start-Sleep -Seconds 5
67 | }
68 |
69 | Write-Verbose "[$((Get-Date).TimeOfDay)] Setting Window size to $($WindowSize -join 'x')"
70 | if ($PSCmdlet.ShouldProcess("WindowsSandboxClient", "Modifying Window size and state")) {
71 | $clientProc = Get-Process -Name WindowsSandboxClient
72 | #values to pass to the function are a percentage of the desired size
73 | #TODO: figure out scaling in display resolution set to scale
74 | [Int]$width = $WindowSize[0] #* .6667
75 | [Int]$Height = $WindowSize[1] # * .6667
76 | Write-Verbose "[$((Get-Date).TimeOfDay)] Modifying handle $($clientproc.mainwindowhandle) with a width of $($WindowSize[0]) and height of $($WindowSize[1])"
77 |
78 | Set-WindowSize -handle $clientproc.MainWindowHandle -width $width -height $height
79 |
80 | #Configure the Windows Sandbox to run minimized (Issue #2)
81 | Write-Verbose "[$((Get-Date).TimeOfDay)] Minimizing child process WindowsSandboxClient"
82 | $clientProc | Set-WindowState -State minimize
83 | }
84 |
85 | if ($Configuration) {
86 | $wsb = Get-WsbConfiguration -Path $Configuration
87 | if ($wsb.LogonCommand) {
88 | Write-Verbose "[$((Get-Date).TimeOfDay)] Running logon command $($wsb.LogonCommand) in the Windows Sandbox."
89 | }
90 |
91 | if ($wsb.MappedFolder) {
92 | Write-Verbose "[$((Get-Date).TimeOfDay)] Mapping these folders"
93 | $wsb.MappedFolder | Out-String | Write-Verbose
94 | }
95 | }
96 | Write-Verbose "[$((Get-Date).TimeOfDay)] Ending $($MyInvocation.MyCommand)."
97 |
98 | Write-Host "[$((Get-Date).TimeOfDay)] Windows Sandbox has been launched. You may need to wait for any configurations to complete." -ForegroundColor green
99 | }
100 |
--------------------------------------------------------------------------------
/functions/private.ps1:
--------------------------------------------------------------------------------
1 |
2 | Function Set-WindowSize {
3 | #from https://gist.github.com/coldnebo/1148334
4 |
5 | [CmdletBinding(SupportsShouldProcess)]
6 | Param(
7 | [Parameter(
8 | Position = 0,
9 | HelpMessage = "What is the MainWindowHandle?",
10 | ValueFromPipeline,
11 | ValueFromPipelineByPropertyName
12 | )]
13 | [ValidateNotNullOrEmpty()]
14 | [Alias("handle")]
15 | [System.IntPtr]$MainWindowHandle = (Get-Process -id $pid).MainWindowHandle,
16 | [Alias("x")]
17 | [Int]$Width = 1280,
18 | [Alias("y")]
19 | [Int]$Height = 720
20 | )
21 |
22 | Begin {
23 | Write-Verbose "Starting $($MyInvocation.MyCommand)"
24 | Write-Verbose "Using a window width of $Width"
25 | Write-Verbose "Using a window Height of $height"
26 | Write-Verbose "Adding type code"
27 |
28 | Add-Type @"
29 | using System;
30 | using System.Runtime.InteropServices;
31 |
32 | public class Win32 {
33 | [DllImport("user32.dll")]
34 | [return: MarshalAs(UnmanagedType.Bool)]
35 | public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
36 |
37 | [DllImport("user32.dll")]
38 | [return: MarshalAs(UnmanagedType.Bool)]
39 | public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
40 |
41 | [DllImport("user32.dll")]
42 | [return: MarshalAs(UnmanagedType.Bool)]
43 | public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
44 | }
45 |
46 | public struct RECT
47 | {
48 | public int Left; // x position of upper-left corner
49 | public int Top; // y position of upper-left corner
50 | public int Right; // x position of lower-right corner
51 | public int Bottom; // y position of lower-right corner
52 | }
53 |
54 | "@
55 |
56 | } #begin
57 |
58 | Process {
59 |
60 | #verify handle and get process
61 | Write-Verbose "Verifying process with MainWindowHandle of $MainWindowhandle"
62 |
63 | $proc = (Get-Process).where( { $_.mainwindowhandle -eq $MainWindowhandle })
64 |
65 | if (-NOT $proc.mainwindowhandle) {
66 | Write-Warning "Failed to find a process with a MainWindowHandle of $MainWndowhandle"
67 | #bail out
68 | Return
69 | }
70 |
71 | Write-Verbose "Creating rectangle objects"
72 | $rcWindow = New-Object RECT
73 | $rcClient = New-Object RECT
74 |
75 | Write-Verbose "Getting current settings"
76 | [Win32]::GetWindowRect($MainWindowHandle, [ref]$rcWindow) | Out-Null
77 | [Win32]::GetClientRect($MainWindowHandle, [ref]$rcClient) | Out-Null
78 | Write-Verbose "rcWindow = $($rcWindow | Out-String)"
79 | Write-Verbose "rcClient = $($rcClient | Out-String)"
80 | Write-Verbose "Setting new coordinates"
81 |
82 | #WhatIf
83 | if ($PSCmdlet.ShouldProcess("$($proc.MainWindowTitle) to $width by $height")) {
84 | $dx = ($rcWindow.Right - $rcWindow.Left) - $rcClient.Right
85 | $dy = ($rcWindow.Bottom - $rcWindow.Top) - $rcClient.Bottom
86 |
87 | Write-Verbose "Moving window using dx = $dx and dy = $dy"
88 |
89 | [void]([Win32]::MoveWindow($MainWindowHandle, 0, 0, $width + $dx, $height + $dy, $true ))
90 |
91 | } #close WhatIf
92 |
93 | } #process
94 |
95 | End {
96 | Write-Verbose "Ending $($MyInvocation.MyCommand)"
97 | } #end
98 |
99 | } #end Set-WindowSize function
100 |
101 | function Set-WindowState {
102 | <#
103 | .LINK
104 | https://gist.github.com/Nora-Ballard/11240204
105 | #>
106 |
107 | [CmdletBinding(DefaultParameterSetName = 'InputObject')]
108 | param(
109 | [Parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true)]
110 | [Object[]] $InputObject,
111 |
112 | [Parameter(Position = 1)]
113 | [ValidateSet('FORCEMINIMIZE', 'HIDE', 'MAXIMIZE', 'MINIMIZE', 'RESTORE',
114 | 'SHOW', 'SHOWDEFAULT', 'SHOWMAXIMIZED', 'SHOWMINIMIZED',
115 | 'SHOWMINNOACTIVE', 'SHOWNA', 'SHOWNOACTIVATE', 'SHOWNORMAL')]
116 | [String] $State = 'SHOW'
117 | )
118 |
119 | Begin {
120 | $WindowStates = @{
121 | 'FORCEMINIMIZE' = 11
122 | 'HIDE' = 0
123 | 'MAXIMIZE' = 3
124 | 'MINIMIZE' = 6
125 | 'RESTORE' = 9
126 | 'SHOW' = 5
127 | 'SHOWDEFAULT' = 10
128 | 'SHOWMAXIMIZED' = 3
129 | 'SHOWMINIMIZED' = 2
130 | 'SHOWMINNOACTIVE' = 7
131 | 'SHOWNA' = 8
132 | 'SHOWNOACTIVATE' = 4
133 | 'SHOWNORMAL' = 1
134 | }
135 |
136 | $Win32ShowWindowAsync = Add-Type -MemberDefinition @'
137 | [DllImport("user32.dll")]
138 | public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
139 | '@ -Name "Win32ShowWindowAsync" -Namespace Win32Functions -PassThru
140 |
141 | if (!$global:MainWindowHandles) {
142 | $global:MainWindowHandles = @{ }
143 | }
144 | }
145 |
146 | Process {
147 | foreach ($process in $InputObject) {
148 | if ($process.MainWindowHandle -eq 0) {
149 | if ($global:MainWindowHandles.ContainsKey($process.Id)) {
150 | $handle = $global:MainWindowHandles[$process.Id]
151 | }
152 | else {
153 | Write-Error "Main Window handle is '0'"
154 | continue
155 | }
156 | }
157 | else {
158 | $handle = $process.MainWindowHandle
159 | $global:MainWindowHandles[$process.Id] = $handle
160 | }
161 |
162 | $Win32ShowWindowAsync::ShowWindowAsync($handle, $WindowStates[$State]) | Out-Null
163 | Write-Verbose ("Set Window State '{1} on '{0}'" -f $MainWindowHandle, $State)
164 | }
165 | }
166 | }
167 |
168 | Function Register-Watcher {
169 | [CmdletBinding(SupportsShouldProcess)]
170 | Param(
171 | [Parameter(HelpMessage = "Enter the full filename and path to the flag file. The file will be created in the sandbox in a shared folder.")]
172 | [ValidateNotNullOrEmpty()]
173 | [String]$Flag = "C:\scripts\sandbox.flag",
174 | [Parameter(HelpMessage = "Enter the title for the toast notification.")]
175 | [String]$Title = "Windows Sandbox",
176 | [Parameter(HelpMessage = "Enter the path to an image file for the toast notification.")]
177 | [ValidateScript( { Test-Path $_ })]
178 | [String]$Logo = "$PSScriptRoot\..\images\sandbox.jpg",
179 | [Parameter(HelpMessage = "Specify the sound to play for the toast notification.")]
180 | [ValidateSet('Default', 'IM', 'Mail', 'Reminder', 'SMS', 'Alarm', 'Alarm2', 'Alarm3',
181 | 'Alarm4', 'Alarm5', 'Alarm6', 'Alarm7', 'Alarm8', 'Alarm9', 'Alarm10', 'Call',
182 | 'Call2', 'Call3', 'Call4', 'Call5', 'Call6', 'Call7', 'Call8', 'Call9', 'Call10',
183 | 'None'
184 | )]
185 | [String]$Sound = "Call10"
186 | )
187 |
188 | #the event subscriber identifier
189 | $SourceID = "WatchWSB"
190 |
191 | if (Test-Path -Path $flag) {
192 | Remove-Item $flag
193 | }
194 |
195 | #check for any left over event subscribers and remove them so we start clean
196 | Try {
197 | $sub = Get-EventSubscriber -SourceIdentifier $SourceID -ErrorAction Stop
198 | $sub | Unregister-Event
199 | }
200 | Catch {
201 | #ignore errors because it means the event subscriber doesn't exist
202 | }
203 |
204 | $rFlag = $flag.replace("\", "\\")
205 | $query = "Select * from __InstanceCreationEvent Within 10 where TargetInstance ISA 'CIM_DATAFILE' AND TargetInstance.Name='$rflag'"
206 |
207 | #define the action scriptblock text
208 | $sb = @"
209 | `$params = @{
210 | Text = "Your Windows Sandbox is ready."
211 | Header = `$(New-BTHeader -Id 1 -Title "$Title")
212 | Applogo = "$logo"
213 | Sound = "$sound"
214 | }
215 |
216 | New-BurntToastNotification @params
217 | Start-Sleep -Seconds 10
218 | Try {
219 | Unregister-Event WatchWSB -erroraction stop
220 | }
221 | Catch {
222 | #don't do anything
223 | }
224 | if (Test-Path $flag) {
225 | Remove-Item $Flag
226 | }
227 | "@
228 |
229 | $action = [scriptblock]::Create($sb)
230 |
231 | if ($PSCmdlet.ShouldProcess($query, "Register Event")) {
232 | Register-CimIndicationEvent -query $query -source $SourceID -Action $action
233 | } #WhatIf
234 | }
235 |
--------------------------------------------------------------------------------
/images/db.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdhitsolutions/WindowsSandboxTools/9f2a0b71140b293c5769b939aac4899d26a1503b/images/db.png
--------------------------------------------------------------------------------
/images/gazoo.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdhitsolutions/WindowsSandboxTools/9f2a0b71140b293c5769b939aac4899d26a1503b/images/gazoo.bmp
--------------------------------------------------------------------------------
/images/sandbox.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdhitsolutions/WindowsSandboxTools/9f2a0b71140b293c5769b939aac4899d26a1503b/images/sandbox.jpg
--------------------------------------------------------------------------------
/images/start-windowssandbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdhitsolutions/WindowsSandboxTools/9f2a0b71140b293c5769b939aac4899d26a1503b/images/start-windowssandbox.png
--------------------------------------------------------------------------------
/wsbScripts/Install-VSCodeSandbox.ps1:
--------------------------------------------------------------------------------
1 | #Install-VSCodeSandbox.ps1
2 |
3 | <#
4 | This script will download and install the most current x64 version of VS Code
5 | and install the PowerShell extension
6 | #>
7 |
8 | $file = Join-Path -Path $env:temp -ChildPath 'VSCodeSetup-x64.exe'
9 | Invoke-WebRequest -Uri "https://update.code.visualstudio.com/latest/win32-x64-user/stable" -OutFile $file -DisableKeepAlive -UseBasicParsing
10 |
11 | $loadInf = '@
12 | [Setup]
13 | Lang=english
14 | Dir=C:\Program Files\Microsoft VS Code
15 | Group=Visual Studio Code
16 | NoIcons=0
17 | Tasks=desktopicon,addcontextmenufiles,addcontextmenufolders,addtopath
18 | @'
19 |
20 | $infPath = Join-Path -path $env:TEMP -child load.inf
21 | $loadInf | Out-File $infPath
22 |
23 | Start-Process -FilePath $file -ArgumentList "/VERYSILENT /LOADINF=${infPath}" -Wait
24 |
25 | #add extensions
26 | Start-Process -FilePath "C:\Program Files\Microsoft VS Code\bin\code.cmd" -ArgumentList "--install-extension ms-vscode.PowerShell"
27 |
28 | if (Test-Path Function:\log) {
29 | log "VSCode Setup Complete"
30 | }
31 |
--------------------------------------------------------------------------------
/wsbScripts/README.md:
--------------------------------------------------------------------------------
1 | # wsbScripts
2 |
3 | The files in this folder can be called from the WSB files. These files are offered as samples of what you might do. This location is referenced by default with the `wsbScripts` variable when you import the module. It is recommended that you create a location outside of this module and copy any of these files to that location. In your PowerShell profile, you can import the module and then update the global variable.
4 |
5 | ```powershell
6 | Import-Module WindowsSandboxTools
7 | $global:wsbScripts = "d:\wsb\code"
8 | ```
9 |
10 | Most of these scripts are intended to be run *IN* the Windows Sandbox, so any paths must be relative to the sandbox.
11 |
--------------------------------------------------------------------------------
/wsbScripts/Set-SandboxDesktop.ps1:
--------------------------------------------------------------------------------
1 | # Set-SandboxDesktop.ps1
2 | # my Pluralsight-related configuration
3 |
4 | function Update-Wallpaper {
5 | [CmdletBinding(SupportsShouldProcess)]
6 | Param(
7 | [Parameter(Position = 0, HelpMessage = "The path to the wallpaper file.")]
8 | [alias("wallpaper")]
9 | [ValidateScript( { Test-Path $_ })]
10 | [String]$Path = $(Get-ItemPropertyValue -Path 'hkcu:\Control Panel\Desktop\' -Name Wallpaper)
11 | )
12 |
13 | Add-Type @"
14 |
15 | using System;
16 | using System.Runtime.InteropServices;
17 | using Microsoft.Win32;
18 |
19 | namespace Wallpaper
20 | {
21 | public class UpdateImage
22 | {
23 | [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
24 |
25 | private static extern int SystemParametersInfo (int uAction, int uParam, string lpvParam, int fuWinIni);
26 |
27 | public static void Refresh(string path)
28 | {
29 | SystemParametersInfo( 20, 0, path, 0x01 | 0x02 );
30 | }
31 | }
32 | }
33 | "@
34 |
35 | if ($PSCmdlet.ShouldProcess($path)) {
36 | [Wallpaper.UpdateImage]::Refresh($Path)
37 | }
38 | }
39 |
40 | Function Restart-Explorer {
41 | <#
42 | .Synopsis
43 | Restart the Windows Explorer process.
44 | #>
45 | [CmdletBinding(SupportsShouldProcess)]
46 | [OutputType("None")]
47 | Param()
48 |
49 | Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Starting $($MyInvocation.MyCommand)"
50 | Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Stopping Explorer.exe process"
51 | Get-Process -Name Explorer | Stop-Process -Force
52 | #give the process time to start
53 | Start-Sleep -Seconds 2
54 | Try {
55 | Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Verifying Explorer restarted"
56 | $p = Get-Process -Name Explorer -ErrorAction stop
57 | }
58 | Catch {
59 | Write-Warning "Manually restarting Explorer"
60 | Try {
61 | Start-Process explorer.exe
62 | }
63 | Catch {
64 | #this should never be called
65 | Throw $_
66 | }
67 | }
68 | Write-Verbose "[$((Get-Date).TimeOfDay) END ] Ending $($MyInvocation.MyCommand)"
69 | }
70 |
71 | #configure the taskbar and hide icons
72 |
73 | <# if (-not (Test-Path -Path hkcu:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer)) {
74 | [void](New-Item -Path hkcu:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer)
75 | } #>
76 |
77 | Set-ItemProperty -Path hkcu:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\ -Name HideClock -Value 1 -force
78 | Set-ItemProperty -Path hkcu:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\ -Name HideSCAVolume -Value 1 -force
79 | Set-ItemProperty -Path hkcu:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\ -Name HideSCANetwork -Value 1 -force
80 |
81 | #hide news feed
82 | Set-ItemProperty -path hkcu:\SOFTWARE\Microsoft\Windows\CurrentVersion\Feeds\ -name ShellFeedsTaskBarViewMode -Value 2 -force
83 |
84 | <# if (-not (Test-Path -Path hkcu:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced)) {
85 | [void](New-Item -Path hkcu:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced)
86 | } #>
87 |
88 | Set-ItemProperty -Path hkcu:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name HideIcons -Value 1 -force
89 |
90 | Write-Host "set wallpaper" -ForegroundColor cyan
91 | #configure wallpaper
92 | Set-ItemProperty -Path 'hkcu:\Control Panel\Desktop\' -Name Wallpaper -Value C:\Pluralsight\Wallpaper\Pluralsight_Wallpaper_Fall_2015_Black.jpg
93 | Set-ItemProperty -Path 'hkcu:\Control Panel\Desktop\' -Name WallpaperOriginX -Value 0
94 | Set-ItemProperty -Path 'hkcu:\Control Panel\Desktop\' -Name WallpaperOriginY -Value 0
95 | Set-ItemProperty -Path 'hkcu:\Control Panel\Desktop\' -Name WallpaperStyle -Value 10
96 |
97 | Update-WallPaper
98 |
99 | <#
100 | This doesn't work completely in newer versions of Windows 10
101 | Invoke-Command {c:\windows\System32\RUNDLL32.EXE user32.dll,UpdatePerUserSystemParameters 1,True}
102 | #this is a bit harsh but it works
103 | #>
104 |
105 | Restart-Explorer
106 |
107 | if (Test-Path function:\log) {
108 | log "Desktop configuration complete"
109 | }
110 |
--------------------------------------------------------------------------------
/wsbScripts/basic.ps1:
--------------------------------------------------------------------------------
1 | Enable-PSRemoting -Force -SkipNetworkProfileCheck
2 | Set-DnsClientServerAddress -ServerAddresses 1.1.1.1 -InterfaceAlias Ethernet
3 | Install-PackageProvider -Name nuget -force -ForceBootstrap -MinimumVersion '2.8.5.201' -Scope AllUsers
4 | Install-Module PSScriptTools,BurntToast -force
5 | New-BurntToastNotification -Text "Basic sandbox setup complete."
--------------------------------------------------------------------------------
/wsbScripts/demo-config.ps1:
--------------------------------------------------------------------------------
1 | #this script runs IN the Windows Sandbox
2 |
3 | $logParams = @{
4 | Filepath = "C:\log\setup.txt"
5 | Append = $True
6 | }
7 |
8 | "[$(Get-Date)] Starting $($MyInvocation.MyCommand)" | Out-File @logParams
9 |
10 | "[$(Get-Date)] Enabling PSRemoting" | Out-File @logParams
11 | Enable-PSRemoting -Force -SkipNetworkProfileCheck
12 |
13 | "[$(Get-Date)] Set DNS Server to 1.1.1.1" | Out-File @logParams
14 | Set-DnsClientServerAddress -InterfaceIndex (Get-NetAdapter).ifIndex -ServerAddresses 1.1.1.1
15 |
16 | "[$(Get-Date)] Install latest nuget package provider" | Out-File @logParams
17 | Install-PackageProvider -name nuget -force -forcebootstrap -scope allusers
18 |
19 | "[$(Get-Date)] Update PackageManagement and PowerShellGet modules" | Out-File @logParams
20 | Install-Module PackageManagement, PowerShellGet -Force
21 |
22 | #run remaining commands in parallel background jobs
23 | "[$(Get-Date)] Update help" | Out-File @logParams
24 | Start-Job -Name "Help-Update" -ScriptBlock { Update-Help -Force }
25 |
26 | "[$(Get-Date)] Installing default modules" | Out-File @logParams
27 | Start-Job -Name "Module-Install" -ScriptBlock { Install-Module PSScriptTools, BurntToast -Force }
28 |
29 | "[$(Get-Date)] Install Windows Terminal" | Out-File @logParams
30 | Start-Job -Name "Windows-Terminal" -ScriptBlock { Install-Module WTToolbox -Force ; Install-WTRelease }
31 |
32 | #wait for everything to finish
33 | "[$(Get-Date)] Waiting for jobs to finish" | Out-File @logParams
34 | Get-Job | Wait-Job
35 |
36 | foreach ($job in (Get-Job)) {
37 | $result = "Job {0} {1} [{2}]" -f $job.name, $job.state, (New-TimeSpan -Start $job.PSBeginTime -End $job.PSEndTime)
38 | "[$(Get-Date)] $result" | Out-File @logParams
39 | }
40 |
41 | "[$(Get-Date)] Starting Windows Terminal" | Out-File @logParams
42 | Start-Process wt.exe "-M new-tab -d C:\ -p Windows PowerShell"
43 |
44 | "[$(Get-Date)] Setting the host notification flag" | Out-File @logParams
45 | Get-Date | Out-File -FilePath c:\scripts\sandbox.flag
46 |
47 | "[$(Get-Date)] Sending toast notification in the Windows Sandbox" | Out-File @logParams
48 |
49 | $params = @{
50 | Text = "Windows Sandbox configuration is complete."
51 | Header = $(New-BTHeader -Id 1 -Title "Your Sandbox")
52 | Silent = $True
53 | }
54 |
55 | New-BurntToastNotification @params
56 |
--------------------------------------------------------------------------------
/wsbScripts/demo.cmd:
--------------------------------------------------------------------------------
1 | REM demo.cmd
2 | REM This code runs in the context of the Windows Sandbox
3 | mkdir c:\log
4 |
5 | REM set execution policy first so that a setup script can be run
6 | powershell.exe -command "&{ Set-ExecutionPolicy RemoteSigned -force }"
7 |
8 | REM Now run the true configuration script
9 | REM C:\Scripts has been mapped to the local C:\Scripts in the WSB file
10 | powershell.exe -file c:\scripts\demo-config.ps1
--------------------------------------------------------------------------------
/wsbScripts/sandbox-basic.cmd:
--------------------------------------------------------------------------------
1 | REM sandbox-basic.cmd
2 | REM This code runs in the context of the Windows Sandbox
3 |
4 | REM set execution policy first so that a setup script can be run
5 | powershell.exe -command "&{Set-ExecutionPolicy RemoteSigned -force}"
6 |
7 | REM Add an all users all hosts profile script
8 | powershell.exe -command "&{'[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12' | out-file C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1 }"
9 |
10 | REM Now run the true configuration script
11 | REM C:\Scripts has been mapped to the local C:\Scripts in the WSB file
12 | powershell.exe -file c:\scripts\wsbScripts\basic.ps1
--------------------------------------------------------------------------------
/wsbScripts/sandbox-config-pluralsight.ps1:
--------------------------------------------------------------------------------
1 | #this script runs IN the Windows Sandbox under Windows PowerShell 5.1
2 |
3 | $SetupPath = "C:\scripts\wsbScripts"
4 |
5 | #create a log file of the configuration process.
6 | Function log {
7 | Param(
8 | [String]$msg,
9 | [String]$log = "C:\work\wsblog.txt"
10 | )
11 |
12 | "[{0}] {1}" -f (Get-Date), $msg | Out-File -FilePath $log -Encoding ascii -Append
13 | }
14 |
15 | log "Install package provider"
16 | Install-PackageProvider -name nuget -force -forcebootstrap -scope allusers
17 |
18 | log "Updating package management"
19 | Install-Module PackageManagement, PowerShellGet, PSReadLine, WTToolbox -Force
20 |
21 | #run updates and installs in the background
22 | log "Updating Windows PowerShell Help"
23 | Start-Job { PowerShell -command { Update-Help -Force } }
24 | log "Installing default modules: PSScriptTools, PSTeachingTools, BurntToast"
25 | Start-Job { Install-Module PSScriptTools, PSTeachingTools, BurntToast -Force }
26 | log "Installing PSReleaseTools and PowerShell 7.x"
27 | Start-Job {
28 | $msi = (Get-Item C:\shared\PowerShell-7.1*msi).FullName
29 | Start-Process -FilePath $msi -ArgumentList "/quiet REGISTER_MANIFEST=1 ADD_PATH=1 ENABLE_PSREMOTING=1 ADD_EXPLORER_CONTEXT_MENU_OPENPowerShell=1 ADD_FILE_CONTEXT_MENU_RUNPowerShell=1" -Wait
30 |
31 | #update help
32 | C:\Program` Files\PowerShell\7\pwsh.exe -command { Update-Help -Force }
33 |
34 | #copy profile
35 | $myprofile = "C:\Pluralsight\Pluralsight-psprofile.ps1"
36 |
37 | Copy-Item -Path $myprofile -Destination 'C:\Program Files\PowerShell\7\profile.ps1'
38 | Install-Module Microsoft.PowerShell.ConsoleGuiTools -force
39 | }
40 |
41 | log "Installing Applications"
42 | Start-Job {
43 | Add-AppxPackage -Path c:\pluralsight\PowerpointViewer.appx
44 | C:\scripts\Download-Winget.ps1 -install -AddPrequisites
45 | # winget install git
46 | winget install microsoft.edge
47 | winget install Microsoft.WindowsTerminal
48 | }
49 |
50 | #set DNS
51 | Set-DnsClientServerAddress -InterfaceIndex (Get-NetAdapter).ifIndex -ServerAddresses 1.1.1.1
52 |
53 | <# log "Hiding tray icons"
54 | Start-Job {
55 | if (-not (Test-Path -path hkcu:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer)) {
56 | [void](New-Item -path hkcu:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer)
57 | }
58 | Set-ItemProperty -path hkcu:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\ -Name HideClock -Value 1
59 | Set-ItemProperty -path hkcu:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\ -Name HideSCAVolume -Value 1
60 | Set-ItemProperty -path hkcu:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\ -Name HideSCANetwork -Value 1
61 | if (-not (Test-Path -path hkcu:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced)) {
62 | [void](New-Item -path hkcu:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced)
63 | }
64 |
65 | Set-ItemProperty -path hkcu:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name HideIcons -Value 1
66 |
67 |
68 | } #>
69 |
70 | log "Installing fonts"
71 | Start-Job {
72 | $FontSource = "C:\Pluralsight\1 INSTALL FONTS"
73 | $shell = New-Object -ComObject Shell.Application -ErrorAction stop
74 | $fontFolder = $shell.Namespace(0x14)
75 | #find already installed font files from the registry
76 | $installedfiles = @()
77 | $regLocation = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts"
78 |
79 | if (Test-Path $reglocation) {
80 | $props = (Get-Item $regLocation).property
81 | if ($props) {
82 | $installedfiles += Get-ItemPropertyValue -Path $reglocation -Name $props
83 | }
84 | }
85 | else {
86 | Write-Warning "$reglocation not found. This is OK."
87 | }
88 | $reguser = 'HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Fonts'
89 | $props = (Get-Item $reguser).property
90 | if ($props) {
91 | Write-Host "Adding $($props.count) user installed fonts"
92 | $installedfiles += Get-ItemPropertyValue -Path $reguser -Name $props | Split-Path -Leaf
93 | }
94 |
95 | Get-ChildItem -Path $Fontsource -File | ForEach-Object {
96 | #Write-Host "Testing $($_.name)"
97 | if ($installedFiles -notcontains $_.name) {
98 | Write-Host "installing $($_.name) from $($_.FullName)" -ForegroundColor green
99 | $fontFolder.copyHere($_.FullName)
100 | }
101 | else {
102 | Write-Host "$($_.name) already installed" -ForegroundColor yellow
103 | }
104 | } #foreach
105 | }
106 |
107 | log "Configure desktop"
108 | Start-Job {
109 | Write-Host "Copy a default profile for all users all hosts" -ForegroundColor cyan
110 | $myprofile = "C:\Pluralsight\Pluralsight-psprofile.ps1"
111 | #Windows PowerShell
112 | Copy-Item -Path $myprofile -Destination 'C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1'
113 |
114 | Write-Host "Configure Trusted Hosts" -ForegroundColor Cyan
115 | Set-Item WSMan:\localhost\Client\TrustedHosts -Value "prospero" -Force -PassThru
116 |
117 | Write-Host "add cmdkey entry for host" -ForegroundColor Cyan
118 | cmdkey /add:Prospero /user:Jeff /pass:Beth2005
119 |
120 | #run configure desktop script
121 | C:\scripts\wsbscripts\Set-SandboxDesktop.ps1
122 |
123 | #hide the search box
124 | Set-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Search -Name SearchBoxTaskbarMode -Value 0 -Type DWord -Force
125 |
126 | Write-Host "auto-hide the Taskbar" -ForegroundColor cyan
127 | . C:\scripts\TaskbarTools.ps1
128 | #this will force a restart of Explorer
129 | Enable-AutoHideTaskBar
130 |
131 | }
132 |
133 | #wait for everything to finish
134 | log "Waiting for background jobs to complete"
135 | Get-Job | Out-String | Out-File "C:\work\wsblog.txt" -Encoding ascii -Append
136 | Get-Job | Wait-Job
137 | #Get-Job | Receive-Job | Out-File "C:\work\wsblog.txt" -Encoding ascii -append
138 |
139 | #reset Explorer so that registry changes take
140 | #log "Resetting Explorer"
141 | #Get-Process Explorer | Stop-Process
142 |
143 | log "Start Windows Terminal"
144 | wt.exe
145 | Start-Sleep -Seconds 5
146 | log "Copy Windows Terminal settings"
147 | Copy-Item -Path c:\shared\settings.json -Destination C:\Users\WDAGUtilityAccount\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json -Force
148 |
149 | #log "Set the flag on the host"
150 | #Get-Date | Out-File -FilePath c:\scripts\sandbox.flag
151 |
152 | log "Ending configuration script"
153 | log "Sending toast notification in the Windows Sandbox"
154 | &(Join-Path -Path $SetupPath -ChildPath sandbox-toast.ps1)
155 |
156 | #Start-Sleep -Seconds 30
157 | #Remove-Item c:\scripts\sandbox.flag
158 |
--------------------------------------------------------------------------------
/wsbScripts/sandbox-config-presentation.ps1:
--------------------------------------------------------------------------------
1 | #this script runs IN the Windows Sandbox
2 |
3 | $SetupPath = "C:\scripts\wsbScripts"
4 |
5 | #create a log file of the configuration process.
6 | Function log {
7 | Param(
8 | [String]$msg,
9 | [String]$log = "C:\work\wsblog.txt"
10 | )
11 |
12 | "[{0}] {1}" -f (Get-Date), $msg | Out-File -FilePath $log -Encoding ascii -Append
13 | }
14 |
15 | log "Updating package management"
16 | Install-Module PackageManagement, PowerShellGet -Force
17 |
18 | #run updates and installs in the background
19 | log "Updating Windows PowerShell Help"
20 | Start-Job { PowerShell -command { Update-Help -Force } }
21 | log "Installing default modules: PSScriptTools, PSTypeExtensionTools,PSTeachingTools, BurntToast"
22 | Start-Job { Install-Module PSScriptTools, PSTeachingTools, PSTypeExtensionTools, BurntToast -Force }
23 | log "Installing PSReleaseTools and PowerShell 7 + Preview"
24 | Start-Job {
25 | Install-Module PSReleaseTools -Force
26 | Install-PowerShell -Mode quiet -EnableRemoting -EnableContextMenu
27 | Install-PSPreview -Mode quiet -EnableRemoting -EnableContextMenu
28 | #update help
29 | C:\Program` Files\PowerShell\7\pwsh.exe -command { Update-Help -Force }
30 | }
31 | log "Installing Windows Terminal"
32 | start-job {
33 | Install-module WTToolbox -force
34 | Install-WindowsTerminal
35 | }
36 |
37 | log "Installing PowerPoint Mobile"
38 | Start-Job { Add-AppxPackage -Path c:\shared\PowerpointViewer.appx }
39 |
40 | log "Installing Applications"
41 | Start-Job {
42 | Function log {
43 | Param(
44 | [String]$msg,
45 | [String]$log = "C:\work\wsblog.txt"
46 | )
47 |
48 | "[{0}] {1}" -f (Get-Date), $msg | Out-File -FilePath $log -Encoding ascii -Append
49 | }
50 | Add-AppxPackage -Path c:\pluralsight\PowerpointViewer.appx
51 | C:\scripts\Download-Winget.ps1 -install -AddPrequisites
52 | if (Get-Command winget) {
53 | log "Installing Git"
54 | winget install git.git
55 | log "Installing VSCode"
56 | winget install Microsoft.visualStudioCode
57 | log "Configuring VSCode"
58 | &'C:\Users\WDAGUtilityAccount\AppData\Local\Programs\Microsoft VS Code\bin\code.cmd' --install-extension ms-vscode.PowerShell
59 | &'C:\Users\WDAGUtilityAccount\AppData\Local\Programs\Microsoft VS Code\bin\code.cmd' --install-extension CoenraadS.bracket-pair-colorizer-2
60 | &'C:\Users\WDAGUtilityAccount\AppData\Local\Programs\Microsoft VS Code\bin\code.cmd' --install-extension TylerLeonhardt.vscode-inline-values-PowerShell
61 | Copy-item -path C:\shared\vscode-settings.json -Destination "c:\Users\WDAGUtilityAccount\AppData\Roaming\Code\User\settings.json"
62 |
63 | Log "Installing Edge"
64 | winget install microsoft.edge
65 | # 8/16/2021 Winget is failing to install this
66 | #Log "Installing Windows Terminal"
67 | 3winget install Microsoft.WindowsTerminal
68 | }
69 |
70 | else {
71 | log "winget not found"
72 | }
73 | }
74 |
75 | #set DNS
76 | log "Configure DNS to 1.1.1.1"
77 | Set-DnsClientServerAddress -InterfaceIndex (Get-NetAdapter).ifIndex -ServerAddresses 1.1.1.1
78 |
79 | #these settings appear to be different for Windows 11
80 | log "Hiding tray icons"
81 | Start-Job {
82 | if (-not (Test-Path -Path hkcu:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer)) {
83 | [void](New-Item -Path hkcu:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer)
84 | }
85 | Set-ItemProperty -Path hkcu:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\ -Name HideClock -Value 1
86 | Set-ItemProperty -Path hkcu:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\ -Name HideSCAVolume -Value 1
87 | Set-ItemProperty -Path hkcu:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\ -Name HideSCANetwork -Value 1
88 | if (-not (Test-Path -Path hkcu:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced)) {
89 | [void](New-Item -Path hkcu:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced)
90 | }
91 |
92 | Set-ItemProperty -Path hkcu:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name HideIcons -Value 1
93 | }
94 | #wait for everything to finish
95 | log "Waiting for background jobs to complete"
96 | Get-Job | Wait-Job
97 |
98 | #reset Explorer so that registry changes take
99 | log "Resetting Explorer"
100 | Get-Process Explorer | Stop-Process
101 |
102 | log "Sending toast notification in the Windows Sandbox"
103 | &(Join-Path -Path $SetupPath -ChildPath sandbox-toast.ps1)
104 |
105 | #set the flag on the host
106 | Get-Date | Out-File -FilePath c:\scripts\sandbox.flag
107 |
108 | log "Ending configuration script"
109 |
--------------------------------------------------------------------------------
/wsbScripts/sandbox-config.ps1:
--------------------------------------------------------------------------------
1 | #this script runs IN the Windows Sandbox
2 |
3 | $SetupPath = "C:\scripts\wsbScripts"
4 |
5 | #create a log file of the configuration process.
6 | Function log {
7 | Param(
8 | [String]$msg,
9 | [String]$log = "C:\work\wsblog.txt"
10 | )
11 |
12 | "[{0}] {1}" -f (Get-Date), $msg | Out-File -FilePath $log -Encoding ascii -Append
13 | }
14 |
15 | #add the logging function to each background job
16 | $init = {
17 | Function log {
18 | Param(
19 | [String]$msg,
20 | [String]$log = "C:\work\wsblog.txt"
21 | )
22 |
23 | "[{0}] {1}" -f (Get-Date), $msg | Out-File -FilePath $log -Encoding ascii -Append
24 | }
25 | }
26 |
27 | #using splatting to pass this parameter. Using PSDefaultParameterValues failed for some reason.
28 | $jobparams = @{InitializationScript = $init}
29 |
30 | $begin = Get-Date
31 | log "Starting Windows Sandbox configuration $($MyInvocation.MyCommand)"
32 | log "Enabling PowerShell remoting"
33 | Enable-PSRemoting -Force -SkipNetworkProfileCheck
34 |
35 | log "Install package provider"
36 | Install-PackageProvider -name nuget -force -forcebootstrap -scope allusers
37 |
38 | log "Updating package management"
39 | Install-Module PackageManagement, PowerShellGet,PSReadLine -Force
40 |
41 | #run updates and installs in the background
42 | log "Setting DNS server to 1.1.1.1"
43 | Set-DnsClientServerAddress -InterfaceIndex (Get-NetAdapter).ifIndex -ServerAddresses 1.1.1.1
44 |
45 | log "Installing VSCode"
46 | Start-Job -name VSCode -FilePath (Join-Path -Path $SetupPath -ChildPath Install-vscodesandbox.ps1) @jobparams
47 |
48 | log "Updating Windows PowerShell Help"
49 | #Start-Job -ScriptBlock { PowerShell -command { Update-Help -Force } ; log "Help updated" } @jobparams
50 | Start-Job -name "Help-Update" -ScriptBlock { Update-Help -Force ; log "Help updated" } @jobparams
51 |
52 | log "Installing default modules: PSScriptTools, PSTeachingTools, BurntToast"
53 | Start-Job -name "Module-Install" -ScriptBlock {
54 | Install-Module PSScriptTools, PSTeachingTools, BurntToast -Force ;
55 | log "PowerShell modules installed" } @jobparams
56 |
57 | log "Installing PSReleaseTools and PowerShell 7 + Preview"
58 | Start-Job -name "PS7-Install" -ScriptBlock {
59 | Install-Module PSReleaseTools -Force
60 | $msi = (Get-Item C:\shared\PowerShell-7.1*.msi).FullName
61 | Start-Process -FilePath $msi -ArgumentList "/quiet REGISTER_MANIFEST=1 ADD_PATH=1 ENABLE_PSREMOTING=1 ADD_EXPLORER_CONTEXT_MENU_OPENPowerShell=1 ADD_FILE_CONTEXT_MENU_RUNPowerShell=1"
62 | $msi = (Get-Item C:\shared\PowerShell-7*preview*.msi).FullName
63 | Start-Process -FilePath $msi -ArgumentList "/quiet REGISTER_MANIFEST=1 ADD_PATH=1 ENABLE_PSREMOTING=1 ADD_EXPLORER_CONTEXT_MENU_OPENPowerShell=1 ADD_FILE_CONTEXT_MENU_RUNPowerShell=1"
64 |
65 | #Install-PowerShell -Mode quiet -EnableRemoting -EnableContextMenu
66 | #Install-PSPreview -Mode quiet -EnableRemoting -EnableContextMenu
67 | #update help
68 | C:\Program` Files\PowerShell\7\pwsh.exe -command { Update-Help -Force }
69 | log "PowerShell 7 installed"
70 | } @jobparams
71 |
72 | log "Installing Windows Terminal"
73 | Start-Job -name "Windows-Terminal" -ScriptBlock { Install-Module WTToolbox -Force ; Install-WTRelease ; log "Windows Terminal installed" } @jobparams
74 |
75 | log "Configuring desktop settings"
76 | Start-Job -Name "Desktop-Config" -FilePath (Join-Path -Path $SetupPath -ChildPath Set-SandboxDesktop.ps1) @jobparams
77 |
78 | log "Installing Winget and additional apps"
79 | Start-Job -name "Winget" -ScriptBlock {
80 | C:\scripts\Download-Winget.ps1 -install -AddPrequisites
81 | winget install git
82 | winget install microsoft.edge
83 | log "Winget and other apps installed"
84 | } @jobparams
85 |
86 | #wait for everything to finish
87 | log "Waiting for background jobs to complete"
88 | Get-Job | Wait-Job
89 |
90 | #add jobs to the log
91 | Get-Job | ForEach-Object {
92 | $msg = "Job: {0} {1} [{2}]" -f $_.name, $_.state, ( New-TimeSpan -Start $_.PSBeginTime -End $_.PSEndTime)
93 | log $msg
94 | }
95 |
96 | log "Starting Windows Terminal"
97 | Start-Process wt.exe "-M new-tab -p PowerShell -d C:\ ; split-pane -V -p Windows PowerShell ; focus-tab --target 0"
98 |
99 | Log "Setting the host notification flag"
100 | Get-Date | Out-File -FilePath c:\scripts\sandbox.flag
101 |
102 | log "Sending toast notification in the Windows Sandbox"
103 | &(Join-Path -Path $SetupPath -ChildPath sandbox-toast.ps1)
104 |
105 | log "Ending configuration script $($MyInvocation.MyCommand)"
106 | log "Configuration completed in $(New-Timespan -start $begin)"
107 | log "Have a nice day!"
108 |
--------------------------------------------------------------------------------
/wsbScripts/sandbox-setup-pluralsight.cmd:
--------------------------------------------------------------------------------
1 | REM sandbox-setup.cmd
2 | REM This code runs in the context of the Windows Sandbox
3 | REM Create my standard Work folder
4 | mkdir c:\work
5 |
6 | REM set execution policy first so that a setup script can be run
7 | REM and then run the configuration script
8 | powershell.exe -command "&{Set-ExecutionPolicy RemoteSigned -force ; Enable-PSRemoting -force -SkipNetworkProfileCheck; Install-PackageProvider -name nuget -force -forcebootstrap -scope allusers;c:\scripts\wsbScripts\sandbox-config-pluralsight.ps1}"
9 |
10 |
--------------------------------------------------------------------------------
/wsbScripts/sandbox-setup-presentation.cmd:
--------------------------------------------------------------------------------
1 | REM sandbox-setup.cmd
2 | REM This code runs in the context of the Windows Sandbox
3 | REM Create my standard Work folder
4 | mkdir c:\work
5 |
6 | REM set execution policy first so that a setup script can be run
7 | REM and then run the configuration script
8 | powershell.exe -command "&{Set-ExecutionPolicy RemoteSigned -force ; Enable-PSRemoting -force -SkipNetworkProfileCheck; Install-PackageProvider -name nuget -force -forcebootstrap -scope allusers;c:\scripts\wsbScripts\sandbox-config-presentation.ps1}"
9 |
10 |
--------------------------------------------------------------------------------
/wsbScripts/sandbox-setup.cmd:
--------------------------------------------------------------------------------
1 | REM sandbox-setup.cmd
2 | REM This code runs in the context of the Windows Sandbox
3 |
4 | REM Create my standard Work folder
5 | mkdir c:\work
6 |
7 | REM set execution policy first so that a setup script can be run
8 | powershell.exe -command "&{Set-ExecutionPolicy RemoteSigned -force}"
9 |
10 | REM Now run the true configuration script
11 | REM C:\Scripts has been mapped to the local C:\Scripts in the WSB file
12 | powershell.exe -file c:\scripts\wsbScripts\sandbox-config.ps1
--------------------------------------------------------------------------------
/wsbScripts/sandbox-toast.ps1:
--------------------------------------------------------------------------------
1 | #sandbox-toast.ps1
2 |
3 | #Send a toast notification in the sandbox when the configuration is complete.
4 | #This will require the BurntToast module to be installed in the Windows Sandbox.
5 |
6 | $params = @{
7 | Text = "Windows Sandbox configuration is complete. See C:\Work\wsblog.txt."
8 | Header = $(New-BTHeader -Id 1 -Title "Windows Sandbox")
9 | Applogo = "c:\scripts\gazoo.bmp"
10 | Silent = $False
11 | }
12 |
13 | New-BurntToastNotification @params
--------------------------------------------------------------------------------
/wsbconfig/README.md:
--------------------------------------------------------------------------------
1 | # wsbConfig
2 |
3 | The files in the folder are sample and reference WSB files. This location is referenced by default with the `wsbConfigPath` variable when you import the module. It is recommended that you create a location outside of this module and copy any of these files to that location. In your PowerShell profile, you can import the module and then update the global variable.
4 |
5 | ```powershell
6 | Import-Module WindowsSandboxTools
7 | $global:wsbConfigPath = "d:\wsb\configs
8 | ```
9 |
10 | You can create new configurations with `New-WsbConfiguration` and then save them to a file with `Export-WsbConfiguration`. File references in the file must use FileSystem paths.
11 |
--------------------------------------------------------------------------------
/wsbconfig/WinSandBx.wsb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | C:\scripts
7 | C:\scripts
8 | false
9 |
10 |
11 | C:\Pluralsight
12 | C:\Pluralsight
13 | true
14 |
15 |
16 | C:\Shared
17 | c:\shared
18 | false
19 |
20 |
21 | Enable
22 | Disable
23 | Disable
24 | Default
25 | 8192
26 |
27 | C:\scripts\wsbScripts\sandbox-setup.cmd
28 |
29 |
30 |
31 |
34 |
--------------------------------------------------------------------------------
/wsbconfig/basic.wsb:
--------------------------------------------------------------------------------
1 |
2 |
3 | C:\scripts\wsbconfig\basic.wsb
4 | Jeff Hicks
5 | Basic sandbox with Scripts and shared folder
6 | 12/21/2020 9:30 AM
7 |
8 | Enable
9 | 8192
10 | Disable
11 | Default
12 | Default
13 | Default
14 | Default
15 | Disable
16 |
17 | C:\scripts\wsbScripts\sandbox-basic.cmd
18 |
19 |
20 |
21 | C:\scripts
22 | C:\scripts
23 | False
24 |
25 |
26 | C:\shared
27 | C:\shared
28 | False
29 |
30 |
31 |
--------------------------------------------------------------------------------
/wsbconfig/demo.wsb:
--------------------------------------------------------------------------------
1 |
2 |
3 | demo
4 | Jeff
5 | This is a demonstration WSB file.
6 | 12/10/2020 09:00:54
7 |
8 | Enable
9 | 8192
10 | Default
11 | Default
12 | Default
13 | Default
14 | Default
15 | Default
16 |
17 | c:\scripts\wsbscripts\demo.cmd
18 |
19 |
20 |
21 | C:\Scripts
22 | C:\Scripts
23 | False
24 |
25 |
26 |
--------------------------------------------------------------------------------
/wsbconfig/pluralsight.wsb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | C:\scripts
7 | C:\scripts
8 | false
9 |
10 |
11 |
12 | C:\Pluralsight
13 | C:\Pluralsight
14 | True
15 |
16 |
17 | C:\Shared
18 | C:\shared
19 | False
20 |
21 |
22 | Enable
23 | Default
24 | 16384
25 |
26 |
27 | C:\scripts\wsbScripts\sandbox-setup-pluralsight.cmd
28 |
29 |
--------------------------------------------------------------------------------
/wsbconfig/presentation.wsb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | C:\scripts
7 | C:\scripts
8 | false
9 |
10 |
11 |
12 | C:\Presentations
13 | C:\presentations
14 | false
15 |
16 |
17 | C:\Shared
18 | C:\shared
19 | False
20 |
21 |
22 | Enable
23 | Default
24 | 8192
25 |
26 |
27 | C:\scripts\wsbScripts\sandbox-setup-presentation.cmd
28 |
29 |
--------------------------------------------------------------------------------
/wsbconfig/sample.wsb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Sample
5 | Jeff Hicks
6 | a simple configuration with drive mappings
7 | 2020-09-10 08:47:10Z
8 |
9 | Enable
10 | Default
11 | 8192
12 |
13 |
14 |
15 | C:\scripts
16 | C:\scripts
17 | true
18 |
19 |
20 |
21 | D:\shared
22 | C:\shared
23 | false
24 |
25 |
26 |
--------------------------------------------------------------------------------
/wsbconfig/work.wsb:
--------------------------------------------------------------------------------
1 |
2 |
3 | work
4 | Jeff
5 | My work WSB configuration
6 | 07/18/2022 15:43:24
7 |
8 | Default
9 | 8192
10 | Default
11 | Default
12 | Default
13 | Default
14 | Default
15 | Default
16 |
17 | C:\scripts\windowssandboxtools\wsbScripts\basic.cmd
18 |
19 |
20 |
21 | c:\work
22 | c:\work
23 | False
24 |
25 |
26 |
--------------------------------------------------------------------------------