Skip to content

Instantly share code, notes, and snippets.

@javiercn
Last active May 10, 2023 01:09
Show Gist options
  • Save javiercn/20fb813bdbbaad1660a9a1142daeb26f to your computer and use it in GitHub Desktop.
Save javiercn/20fb813bdbbaad1660a9a1142daeb26f to your computer and use it in GitHub Desktop.
Developer-sandbox
<Configuration>
<MappedFolders>
<MappedFolder>
<HostFolder>C:\work\WindowsSandbox\DevelopmentSandboxShare</HostFolder>
<ReadOnly>true</ReadOnly>
</MappedFolder>
</MappedFolders>
<LogonCommand>
<Command>powershell -noexit -executionpolicy bypass -File C:\Users\WDAGUtilityAccount\Desktop\DevelopmentSandboxShare\DeveloperSandboxSetup.ps1</Command>
</LogonCommand>
</Configuration>
Set-ExecutionPolicy Bypass -Scope Process -Force;
$visualStudioSetup = @'
<#
.SYNOPSIS
Installs or updates Visual Studio on a local developer machine.
.DESCRIPTION
This installs Visual Studio along with all the workloads required to contribute to this repository.
.PARAMETER Edition
Selects which 'offering' of Visual Studio to install. Must be one of these values:
BuildTools
Community
Professional
Enterprise (the default)
.PARAMETER Channel
Selects which channel of Visual Studio to install. Must be one of these values:
Release (the default)
Preview
.PARAMETER InstallPath
The location on disk where Visual Studio should be installed or updated. Default path is location of latest
existing installation of the specified edition, if any. If that VS edition is not currently installed, default
path is '${env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\`$Edition".
.PARAMETER Passive
Run the installer without requiring interaction.
.PARAMETER Quiet
Run the installer without UI and wait for installation to complete.
.LINK
https://visualstudio.com
https://github.com/aspnet/AspNetCore/blob/master/docs/BuildFromSource.md
.EXAMPLE
To install VS 2019 Enterprise, run this command in PowerShell:
.\InstallVisualStudio.ps1
#>
param(
[ValidateSet('BuildTools','Community', 'Professional', 'Enterprise')]
[string]$Edition = 'Enterprise',
[ValidateSet('Release', 'Preview')]
[string]$Channel = 'Release',
[string]$InstallPath,
[switch]$Passive,
[switch]$Quiet
)
if ($env:TF_BUILD) {
Write-Error 'This script is not intended for use on CI. It is only meant to be used to install a local developer environment. If you need to change Visual Studio requirements in CI agents, contact the @aspnet/build team.'
exit 1
}
if ($Passive -and $Quiet) {
Write-Host -ForegroundColor Red "Error: The -Passive and -Quiet options cannot be used together."
Write-Host -ForegroundColor Red "Run ``Get-Help $PSCommandPath`` for more details."
exit 1
}
$ErrorActionPreference = 'Stop'
Set-StrictMode -Version 1
$intermedateDir = "$PSScriptRoot"
mkdir $intermedateDir -ErrorAction Ignore | Out-Null
$bootstrapper = "$intermedateDir\vsinstaller.exe"
$ProgressPreference = 'SilentlyContinue' # Workaround PowerShell/PowerShell#2138
$channelUri = "https://aka.ms/vs/16/release"
$responseFileName = "vs"
if ("$Edition" -eq "BuildTools") {
$responseFileName += ".buildtools"
}
if ("$Channel" -eq "Preview") {
$responseFileName += ".preview"
$channelUri = "https://aka.ms/vs/16/pre"
}
$responseFile = "$PSScriptRoot\$responseFileName.json"
$channelId = (Get-Content $responseFile | ConvertFrom-Json).channelId
$bootstrapperUri = "$channelUri/vs_$($Edition.ToLowerInvariant()).exe"
Write-Host "Downloading Visual Studio 2019 $Edition ($Channel) bootstrapper from $bootstrapperUri"
Invoke-WebRequest -Uri $bootstrapperUri -OutFile $bootstrapper
$productId = "Microsoft.VisualStudio.Product.$Edition"
if (-not $InstallPath) {
$vsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
if (Test-Path $vsWhere)
{
$installations = & $vsWhere -version '[16,17)' -format json -sort -prerelease -products $productId | ConvertFrom-Json
foreach ($installation in $installations) {
Write-Host "Found '$($installation.installationName)' in '$($installation.installationPath)', channel = '$($installation.channelId)'"
if ($installation.channelId -eq $channelId) {
$InstallPath = $installation.installationPath
break
}
}
}
}
if (-not $InstallPath) {
if ("$Channel" -eq "Preview") {
$InstallPath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\${Edition}_Pre"
} else {
$InstallPath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\$Edition"
}
}
# no backslashes - this breaks the installer
$InstallPath = $InstallPath.TrimEnd('\')
[string[]] $arguments = @()
if (Test-path $InstallPath) {
$arguments += 'modify'
}
$arguments += `
'--productId', $productId, `
'--installPath', "`"$InstallPath`"", `
'--in', "`"$responseFile`"", `
'--norestart'
if ($Passive) {
$arguments += '--passive'
}
if ($Quiet) {
$arguments += '--quiet', '--wait'
}
Write-Host
Write-Host "Installing Visual Studio 2019 $Edition ($Channel)" -f Magenta
Write-Host
Write-Host "Running '$bootstrapper $arguments'"
foreach ($i in 0, 1, 2) {
if ($i -ne 0) {
Write-Host "Retrying..."
}
$process = Start-Process -FilePath "$bootstrapper" -ArgumentList $arguments -ErrorAction Continue -PassThru `
-RedirectStandardError "$intermedateDir\errors.txt" -Verbose -Wait
Write-Host "Exit code = $($process.ExitCode)."
if ($process.ExitCode -eq 0) {
break
} else {
# https://docs.microsoft.com/en-us/visualstudio/install/use-command-line-parameters-to-install-visual-studio#error-codes
if ($process.ExitCode -eq 3010) {
Write-Host -ForegroundColor Red "Error: Installation requires restart to finish the VS update."
break
}
elseif ($process.ExitCode -eq 5007) {
Write-Host -ForegroundColor Red "Error: Operation was blocked - the computer does not meet the requirements."
break
}
elseif (($process.ExitCode -eq 5004) -or ($process.ExitCode -eq 1602)) {
Write-Host -ForegroundColor Red "Error: Operation was canceled."
}
else {
Write-Host -ForegroundColor Red "Error: Installation failed for an unknown reason."
}
Write-Host
Write-Host "Errors:"
Get-Content "$intermedateDir\errors.txt" | Write-Warning
Write-Host
Get-ChildItem $env:Temp\dd_bootstrapper_*.log |Sort-Object CreationTime -Descending |Select-Object -First 1 |% {
Write-Host "${_}:"
Get-Content "$_"
Write-Host
}
$clientLogs = Get-ChildItem $env:Temp\dd_client_*.log |Sort-Object CreationTime -Descending |Select-Object -First 1 |% {
Write-Host "${_}:"
Get-Content "$_"
Write-Host
}
$setupLogs = Get-ChildItem $env:Temp\dd_setup_*.log |Sort-Object CreationTime -Descending |Select-Object -First 1 |% {
Write-Host "${_}:"
Get-Content "$_"
Write-Host
}
}
}
Remove-Item "$intermedateDir\errors.txt" -errorAction SilentlyContinue
Remove-Item $intermedateDir -Recurse -Force -ErrorAction SilentlyContinue
exit $process.ExitCode
'@
$installerJson = @'
{
"channelUri": "https://aka.ms/vs/16/pre/channel",
"channelId": "VisualStudio.16.Preview",
"includeRecommended": false,
"addProductLang": [
"en-US"
],
"add": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.6.2.TargetingPack",
"Microsoft.Net.Component.4.7.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.Net.Component.4.7.TargetingPack",
"Microsoft.VisualStudio.Component.Azure.Storage.Emulator",
"Microsoft.VisualStudio.Component.VC.ATL",
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
"Microsoft.VisualStudio.Component.Windows10SDK.17134",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NativeDesktop",
"Microsoft.VisualStudio.Workload.NetCoreTools",
"Microsoft.VisualStudio.Workload.NetWeb",
"Microsoft.VisualStudio.Workload.VisualStudioExtension"
]
}
'@
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
choco install pwsh -y
choco install msbuild-structured-log-viewer -y
choco install ilspy -y
choco install nodejs -y
choco install dotnetcore-sdk -y
choco install googlechrome -y
choco install vscode -y
choco install git -y
$sandboxWd = "$env:USERPROFILE\.sandbox\";
mkdir $sandboxWd;
Push-Location $sandboxWd;
Out-File InstallVisualStudio.ps1 -InputObject $visualStudioSetup;
Out-File vs.preview.json -InputObject $installerJson;
.\InstallVisualStudio.ps1 -Passive -Channel Preview -Edition Professional
Pop-Location
Set-ExecutionPolicy -ExecutionPolicy Bypass -Force;
Register-ScheduledJob -Name CreateProjects -ScriptBlock { C:\Users\WDAGUtilityAccount\Desktop\DevelopmentSandboxShare\DotNetProjectCreationScripts.ps1 } -RunNow
Start-Sleep -Seconds 2;
Get-Job CreateProjects | Wait-Job | Receive-Job;
Register-ScheduledJob -Name InstallDotNetTools -ScriptBlock { C:\Users\WDAGUtilityAccount\Desktop\DevelopmentSandboxShare\DotNetToolsInstallation.ps1 } -RunNow
Start-Sleep -Seconds 2;
Get-Job InstallDotNetTools | Wait-Job | Receive-Job;
Start-Process "$env:USERPROFILE\source\repos\Validation";
# Creates all the project types with their most common options as a way
# to make issue investigations, repros and validations faster and easier
# to perform.
# Note currently the projects using local DB won't work in the Windows Sandbox
# Replace this with the target SDK you want to use.
$sdk = "3.0.100";
$repos = "$env:USERPROFILE\source\repos\Validation";
if (-not (Test-Path $repos)) {
New-Item -ItemType Directory $repos | Out-Null;
}
Push-Location $repos;
if ($sdk) {
dotnet new globaljson --sdk-version $sdk;
}
# Empty template
dotnet new web -o .\EmptyApp\EmptyApp;
Push-Location EmptyApp;
dotnet new sln;
dotnet sln add .\EmptyApp;
Pop-Location;
# Razor pages
dotnet new webapp -o .\RazorPagesNoAuth\RazorPagesNoAuth;
Push-Location RazorPagesNoAuth;
dotnet new sln;
dotnet sln add .\RazorPagesNoAuth;
Pop-Location;
# Razor pages with Identity and local DB
dotnet new webapp -au Individual -uld -o .\RazorPagesIndividualLocalDb\RazorPagesIndividualLocalDb;
Push-Location RazorPagesIndividualLocalDb;
dotnet new sln;
dotnet sln add .\RazorPagesIndividualLocalDb;
Pop-Location;
# Razor pages with Identity and SQL lite
dotnet new webapp -au Individual -o .\RazorPagesIndividualSqlLite\RazorPagesIndividualSqlLite;
Push-Location RazorPagesIndividualSqlLite;
dotnet new sln;
dotnet sln add .\RazorPagesIndividualSqlLite;
Pop-Location;
# Razor pages with Razor class library
dotnet new webapp -o .\RazorPagesWithClassLib\RazorPagesWithClassLib;
dotnet new razorclasslib -s -o .\RazorPagesWithClassLib\RazorClassLibPagesAndViews;
Push-Location RazorPagesWithClassLib;
dotnet new sln;
dotnet sln add .\RazorPagesWithClassLib;
dotnet sln add .\RazorClassLibPagesAndViews;
dotnet add .\RazorPagesWithClassLib reference .\RazorClassLibPagesAndViews;
Pop-Location;
# MVC
dotnet new mvc -o .\MvcNoAuth\MvcNoAuth;
Push-Location MvcNoAuth;
dotnet new sln;
dotnet sln add .\MvcNoAuth;
Pop-Location;
# MVC with Identity and local DB
dotnet new mvc -au Individual -uld -o .\MvcIndividualLocalDb\MvcIndividualLocalDb;
Push-Location MvcIndividualLocalDb;
dotnet new sln;
dotnet sln add .\MvcIndividualLocalDb;
Pop-Location;
# MVC with Identity and SQL lite
dotnet new mvc -au Individual -o .\MvcIndividualSqlLite\MvcIndividualSqlLite;
Push-Location MvcIndividualSqlLite;
dotnet new sln;
dotnet sln add .\MvcIndividualSqlLite;
Pop-Location;
# MVC with Razor class library
dotnet new mvc -o .\MvcWithClassLib\MvcWithClassLib;
dotnet new razorclasslib -s -o .\MvcWithClassLib\RazorClassLibPagesAndViews;
Push-Location MvcWithClassLib;
dotnet new sln;
dotnet sln add .\MvcWithClassLib;
dotnet sln add .\RazorClassLibPagesAndViews;
dotnet add .\MvcWithClassLib reference .\RazorClassLibPagesAndViews;
Pop-Location;
# Server-side Blazor
dotnet new blazorserver -o .\BlazorServerNoAuth\BlazorServerNoAuth;
Push-Location BlazorServerNoAuth;
dotnet new sln;
dotnet sln add .\BlazorServerNoAuth;
Pop-Location;
# Server-side Blazor with Identity and local DB
dotnet new blazorserver -au Individual -uld -o .\BlazorServerIndividualLocalDb\BlazorServerIndividualLocalDb;
Push-Location BlazorServerIndividualLocalDb;
dotnet new sln;
dotnet sln add .\BlazorServerIndividualLocalDb;
Pop-Location;
# Server-side Blazor with Identity and SQL lite
dotnet new blazorserver -au Individual -o .\BlazorServerIndividualSqlLite\BlazorServerIndividualSqlLite;
Push-Location BlazorServerIndividualSqlLite;
dotnet new sln;
dotnet sln add .\BlazorServerIndividualSqlLite;
Pop-Location;
# Server-side Blazor with Razor class library
dotnet new blazorserver -o .\BlazorServerWithClassLib\BlazorServerWithClassLib;
dotnet new razorclasslib -o .\BlazorServerWithClassLib\RazorClassLibNoPages;
Push-Location BlazorServerWithClassLib;
dotnet new sln;
dotnet sln add .\BlazorServerWithClassLib;
dotnet sln add .\RazorClassLibNoPages;
dotnet add .\BlazorServerWithClassLib reference .\RazorClassLibNoPages;
Pop-Location;
# Angular
dotnet new angular -o .\AngularNoAuth\AngularNoAuth;
Push-Location AngularNoAuth;
dotnet new sln;
dotnet sln add .\AngularNoAuth;
Pop-Location;
# Angular with Identity and local DB
dotnet new angular -au Individual -uld -o .\AngularIndividualLocalDb\AngularIndividualLocalDb;
Push-Location AngularIndividualLocalDb;
dotnet new sln;
dotnet sln add .\AngularIndividualLocalDb;
Pop-Location;
# Angular with Identity and SQL lite
dotnet new angular -au Individual -o .\AngularIndividualSqlLite\AngularIndividualSqlLite;
Push-Location AngularIndividualSqlLite;
dotnet new sln;
dotnet sln add .\AngularIndividualSqlLite;
Pop-Location;
# React
dotnet new react -o .\ReactNoAuth\ReactNoAuth;
Push-Location ReactNoAuth;
dotnet new sln;
dotnet sln add .\ReactNoAuth;
Pop-Location;
# React with Identity and local DB
dotnet new react -au Individual -uld -o .\ReactIndividualLocalDb\ReactIndividualLocalDb;
Push-Location ReactIndividualLocalDb;
dotnet new sln;
dotnet sln add .\ReactIndividualLocalDb;
Pop-Location;
# React with Identity and SQL lite
dotnet new react -au Individual -o .\ReactIndividualSqlLite\ReactIndividualSqlLite;
Push-Location ReactIndividualSqlLite;
dotnet new sln;
dotnet sln add .\ReactIndividualSqlLite;
Pop-Location;
# ReactRedux
dotnet new reactredux -o .\ReactReduxNoAuth\ReactReduxNoAuth;
Push-Location ReactReduxNoAuth;
dotnet new sln;
dotnet sln add .\ReactReduxNoAuth;
Pop-Location;
# Leaves $repos
Pop-Location;
# Installs .NET global tools that are handy for
# testing purposes
# This is done to install the tools based on the forced SDK
$repos = "$env:USERPROFILE\source\repos\Validation";
Push-Location $repos;
dotnet tool install --global dotnet-dump
dotnet tool install --global dotnet-trace
dotnet tool install --global dotnet-counters
Pop-Location
@javiercn
Copy link
Author

javiercn commented Oct 8, 2019

Notes

To use this you need to enable the windows sandbox (see Installation for details).

You need to download this gist and unzip it inside C:\work\WindowsSandbox

You can pin the DevelopmentSandbox.wsb file to your task bar and start it by right clicking on it and selecting DevelopmentSandbox.

The user is WDAGUtilityAccount
To change the password open a command prompt and run net user WDAGUtilityAccount *
The password will be reset every time you close the sandbox

The machine creates a list of the most common projects ready to go inside C:\Users\WDAGUtilityAccount\sources\repo\Validation

  • You can tweak this by modifying DotNetProjectCreationScripts.ps1
  • It creates the projects using the latest released SDK (currently 3.0.100) and it uses a global.json to leave it locked.
  • The script are on C:\Users\WDAGUtilityAccount\Desktop\DevelopmentSandboxShare in case you want to re-run them against an SDK being validated.

The profile installs most things you need:

  • VS Preview with our workloads.
  • VS Code
  • Chrome
  • Nodejs
  • Powershell Core
  • The latest dotnet core SDK
  • git
  • MSBuild structured log viewer
  • ILSpy

You can install additional tools with choco install <> -y

If you find something missing that is useful, let me know and I can add it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment