Windows
Installation
Creating a Installation USB
You can download Windows 10 directly from the Microsoft website. Choose a USB drive of at least 8GB for the tool to format and create a bootable installer.
If the error 715-123130 appears, try changing your browser or downloading through a VPN in the USA.
If you download the ISO, verify the hash:
PS > Get-FileHash .\Win11_22H2_EnglishInternational_x64v1.iso
Algorithm Hash
--------- ----
SHA256 F115CD6B31734BC091BC94B964D5AD43984285BF229503481E2F7EF94AB7140E
I recommend Rufus for burning the image. It has some very interesting features.
Partitioning
A typical Windows installation creates 4 partitions:
- EFI: 100 MB
- MSR: 16 MB
- Windows
- Recovery: 500 MB to 650 MB
The value you should enter in the graphical installer is the sum of all these partitions. If you
want your C:
to show exactly 250 GB, you should use something slightly larger than 256616 MB
(100 + 16 + 250 * 1024 + 500).
For more control over the sizes, you can partition the disk via command line. Press Shift + F10
and use diskpart
:
diskpart
list disk
select disk 0
clean
convert gpt
create partition efi size=1024
format quick fs=fat32 label="System"
assign letter="S"
create partition msr size=16
create partition primary size=256000
format quick fs=ntfs label="Windows"
assign letter="W"
create partition primary size=700
format quick fs=ntfs label="Recovery"
assign letter="R"
set id="de94bba4-06d1-4d40-a16a-bfd50179d6ac"
gpt attributes=0x8000000000000001
list volume
exit
In this example, an EFI partition with 1 GB and a Recovery partition with 700 MB are created.
An EFI with at least 300 MB is recommended for those who dual boot. Linux mounts this partition as
/boot
and stores files used by the bootloader, including compressed versions of the kernel and
drivers (vmlinuz).
If you already have an EFI partition formatted in FAT32 before starting the installation, Windows will use it instead of creating a new one.
If you realize you need to increase the EFI partition after Windows is already installed, check out Macrorit’s Partition Expert. The free portable version can easily resize and move partitions.
The 16MB MSR (Microsoft Reserved) partition can be restored by Windows itself
(create partition msr
) or by using the code 0c01
in cgdisk
.
Privacy options
A privacy screen appears on the first boot. Uncheck Find my device
, Inking & Typing
,
Advertising ID
, Diagnostic data
, Tailored experiences
, and any other options to uncheck during
installation.
After starting the system, go to Settings » Privacy
. I uncheck almost all options. The only app
that needs access to my camera (which is covered) is Skype.
Group Policy Editor
Run gpedit.msc
.
-
Web search
Go to
Local Computer Policy » Computer Configuration » Administrative Templates » Windows Components » Search
and enable the option “Do not allow web search”. -
BitLocker with PIN
Navigate to
Computer Configuration
»Administrative Templates
»Windows Components
»BitLocker Drive Encryption
»Operating System Drives
and enableRequire Additional Authentication at Startup
andAllow enhanced PINs for startup
. -
Disable Skype’s Meet Now feature
Go to
User Configuration
»Administrative templates
»Start Menu and Taskbar
and enable the policyRemove the Meet Now icon
.
Regedit
-
Disable Cortana and Bing
Navigate to
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search
and create a new DWORD namedConnectedSearchUseWeb
and assign it a value of 0.Navigate to
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Search
and create two new DWORDs with a value of 0:AllowSearchToUseLocation
andBingSearchEnabled
. -
Use UTC in the clock (useful for dual-booting)
Navigate to
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation
and create a new DWORD namedRealTimeIsUniversal
with a value of 1. -
Show/Hide desktop icons
This can be done through the graphical interface, so I do not recommend doing it through regedit.
Computer: {20D04FE0-3AEA-1069-A2D8-08002B30309D} User Files: {59031a47-3f72-44a7-89c5-5595fe6b30ee} Control Panel: {5399E694-6CE5-4D6C-8FCE-1D8870FDCBA0} Network: {F02C1A0D-BE21-4350-88B0-7367FC96EF3C} Recycle Bin: {645FF040-5081-101B-9F08-00AA002F954E}
Example:
reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel /V {20D04FE0-3AEA-1069-A2D8-08002B30309D} /T REG_DWORD /D 0x0 /F
reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\ClassicStartMenu /V {20D04FE0-3AEA-1069-A2D8-08002B30309D} /T REG_DWORD /D 0x0 /F
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel /V {20D04FE0-3AEA-1069-A2D8-08002B30309D} /T REG_DWORD /D 0x0 /F
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\ClassicStartMenu /V {20D04FE0-3AEA-1069-A2D8-08002B30309D} /T REG_DWORD /D 0x0 /F
- Does not show recent files
reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer /V ShowRecent /T REG_DWORD /D 0x0 /F
- Show user folder in File Explorer navigation (quick access)
reg add HKCU\SOFTWARE\Classes\CLSID\{59031a47-3f72-44a7-89c5-5595fe6b30ee} /V System.IsPinnedToNameSpaceTree /T REG_DWORD /D 0x1 /F
Computer Name
Navigate to Control Panel\System and Security\System
. On the line with the computer name, click on
Change settings and change the computer name.
Windows Update
Update everything and restart the computer.
The latest update may not yet be available through Windows Update, but it can be installed manually: https://www.microsoft.com/en-us/software-download/windows10.
Drivers
- Kensington Works
- Nvidia
- Manufacturer’s website
Encryption
-
BitLocker
After updating Windows, enable BitLocker on the C:/ drive. Save the recovery key in a secure location (not on the computer itself, of course).
-
VeraCrypt
It is an open-source alternative that can be used to encrypt entire partitions or create containers. Later on, I will show how to install it using Chocolatey.
Windows Features
Go to Control Panel\Programs » Turn Windows features on or off
.
- Enable “Virtual Machine Platform”
- Enable “Windows Hypervisor Platform” (required for Docker).
- Enable “Windows Sandbox”
- Enable “Windows Subsystem for Linux”
- Enable “Hyper-V” (for virtual machines)
Power
Navigate to Control Panel\Hardware and Sound\Power Options\Create a Power Plan
and create a power
plan based on High Performance with the following options (in advanced power settings):
- Turn off hard disk after
- On battery: 30 Minutes
- Plugged in: Never
- Sleep
- Sleep after
- On battery: 300 Minutes
- Plugged in: Never
- Sleep after
- Power buttons and lid
- Lid close action
- On battery: Do nothing
- Plugged in: Do nothing
- Power button action
- On battery: Sleep
- Plugged in: Do nothing
- Lid close action
- Display
- Turn off display after
- On battery: 20 Minutes
- Plugged in: 30 Minutes
- Turn off display after
In Control Panel\Hardware and Sound\Power Options\System Settings
, uncheck the option
Turn on fast start-up
.
Inactivity Lock
- Screen Saver settings » Blank » 3 min » On resume, display log-on screen
Uninstall unnecessary programs
In Add or Remove programs, uninstall what you won’t use.
Disable annoying messages
Go to
Control Panel\System and Security\Security and Maintenance\Change Security and Maintenance settings
.
Uncheck the option to receive messages about Windows Backup.
Chocolatey
Install following the most current instructions at https://chocolatey.org/install.
In PowerShell as Admin:
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
choco install -y `
7zip `
calibre `
discord `
ditto `
Firefox `
git `
GoogleChrome `
greenshot `
jellyfin-media-player `
nerd-fonts-Hack `
obs-studio `
slack `
spotify `
steam `
telegram `
transgui `
vlc `
vscode `
wireguard
choco install -y `
ack `
bleachbit `
clonespy `
Cmder `
curl `
darktable `
dbeaver `
digikam `
docker-desktop `
eartrumpet `
Everything `
FreeDownloadManager `
gimp `
gnupg `
google-drive-file-stream `
imagemagick `
irfanview `
jre8 `
mariadb `
microsoft-teams `
miniconda3 `
neovim `
nerd-fonts-CascadiaCode `
nerd-fonts-FiraCode `
nodejs `
notepadplusplus `
okular `
postman `
powershell-core `
powertoys `
restic `
rsync `
sourcetree `
sql-server-management-studio `
thunderbird `
transmission `
treesizefree `
vb-cable `
vcxsrv `
veracrypt `
voicemeeter-banana `
winscp
Update Chocolatey
-
List outdated packages:
choco outdated
-
Update Chocolatey first:
choco upgrade chocolatey
-
Update all packages:
choco upgrade all -y
PowerShell
Windows 10 and 11 come with version 5.1 installed, but the newest version is available on GitHub and can be installed through Chocolatey or winget.
winget search Microsoft.PowerShell
winget install --id Microsoft.Powershell --source winget
> $PSVersionTable.PSVersion
Major Minor Patch PreReleaseLabel BuildLabel
----- ----- ----- --------------- ----------
7 4 1
Execution Policy
PowerShell has the following options to restrict script execution:
Restricted
: Does not run scripts. Use PowerShell only in interactive mode.AllSigned
: Runs only scripts signed by a trusted publisher.RemoteSigned
: Downloaded scripts need to be signed.Unrestricted
: All scripts can be run.
I will configure using the RemoteSigned option:
Set-ExecutionPolicy RemoteSigned
Oh My Posh
Oh My Posh is a Terminal theme that is especially good for PowerShell.
The easiest way to install it is with Winget:
winget install JanDeDobbeleer.OhMyPosh -s winget
Then configure PowerShell to start Oh My Posh:
notepad $PROFILE
And paste the following:
oh-my-posh init pwsh --config "$env:POSH_THEMES_PATH/powerlevel10k_lean.omp.json" | Invoke-Expression
Set-PSReadlineOption -EditMode vi -BellStyle None
These commands will configure PowerShell to use the powerlevel10k_lean
theme in vi mode. Other
themes can be previewed with the Get-PoshThemes
command and on the
official website.
The notepad $PROFILE
command edits the $profile.currentusercurrenthost
. If you want to configure
for other hosts and users, edit the appropriate file:
$profile.currentusercurrenthost
C:\Users\Julio\Documents\PowerShell\Microsoft.PowerShell_profile.ps1
$profile.currentuserallhosts
C:\Users\Julio\Documents\PowerShell\profile.ps1
$profile.alluserscurrenthost
C:\Program Files\PowerShell\7\Microsoft.PowerShell_profile.ps1
$profile.allusersallhosts
C:\Program Files\PowerShell\7\profile.ps1
Office
I share a Microsoft 365 Family subscription with 5 other people. I consider it very worthwhile because in addition to Office, each person also gets 1 TB of OneDrive. Furthermore, we often find promotions for a prepaid 1-year Personal subscription, which can be converted into 9 months of Family.
The installer with all Office 365 programs can be downloaded from your Microsoft account. There you choose the language and version (32 or 64-bit).
It is also possible to install each program separately from the Microsoft Store, but I do not recommend it.
Emails
I like to use Thunderbird as my email client.
- To save space, uncheck the option to sync folders. This way, only the headers will be downloaded;
- Set it to minimize to the taskbar;
- Register your PGP key to sign emails;
- Use a master password to protect the passwords and keys saved in Thunderbird (file
key4.db
):Tools » Options » Privacy & Security » use a master password
.
To set up emails that use Two-factor authentication, you can use a specific app password or set up initially without a password and then change it to OAuth2.
Calendar
For most people, leaving the email tab open in the browser and enabling notifications should be enough, but I use multiple calendars and like to keep track of them in one place and receive event alerts on the desktop.
The default Windows app is fully integrated with the system and allows you to view events directly in the taskbar and receive native notifications, but since I already use Thunderbird for emails, I also prefer to configure it to sync my calendars.
Display calendar only (view only)
The link to your Google calendar can be obtained as follows:
- Go to Google Calendar settings (https://calendar.google.com/calendar/u/0/r/settings);
- Settings for my calendars
- Select the calendar;
- Integrate calendar;
- Secret address in iCal format
Paste this link into Thunderbird: File » New » Calendar » On the Network » iCalendar (ICS)
.
The calendar will be marked as read-only.
To view events on the main screen: View » Today Pane » Show Today Pane
.
Bi-directional synchronization (view & edit)
The add-ons Lightning and Provider for Google have this functionality, but you can also configure Thunderbird to use CalDav as follows:
- Google: create a specific password at https://myaccount.google.com/apppasswords.
- Zoho: 1. Create a specific password at Zoho Accounts » Security » App Passwords »
Application-Specific Passwords » Generate New Password. 2. Activate CalDav at Settings »
Calendar » Synchronize » CalDAV. 3. Get the Calendar ID at Settings » Calendars » My
Calendars In Thunderbird, go to
File » New » Calendar » On the Network » CalDAV
. - Username: your@email.com
- Google Location:
https://www.google.com/calendar/dav/your@email.com/events
- Zoho Location:
https://calendar.zoho.com/caldav/**Calendar ID**/events
Languages
I like to keep my notebook in English, but it’s good to add other languages like Portuguese.
Settings » Languages » Preferred Languages » Add a preferred language
.
Add/remove languages via PowerShell
PS > $langs = Get-WinUserLanguageList
PS > $langs
LanguageTag : en-GB
Autonym : English (United Kingdom)
EnglishName : English
LocalizedName : English (United Kingdom)
ScriptName : Latin
InputMethodTips : {0809:00020409}
Spellchecking : True
Handwriting : False
PS > $langs.Add('de-DE')
PS > $langs
LanguageTag : en-GB
Autonym : English (United Kingdom)
EnglishName : English
LocalizedName : English (United Kingdom)
ScriptName : Latin
InputMethodTips : {0809:00020409}
Spellchecking : True
Handwriting : False
LanguageTag : de-DE
Autonym : Deutsch (Deutschland)
EnglishName : German
LocalizedName : German (Germany)
ScriptName : Latin
InputMethodTips : {0407:00000407}
Spellchecking : True
Handwriting : False
PS > Set-WinUserLanguageList $langs -Force
PS > $langs.Remove(($langs | Where-Object LanguageTag -like 'de-DE'))
True
PS > $langs
LanguageTag : en-GB
Autonym : English (United Kingdom)
EnglishName : English
LocalizedName : English (United Kingdom)
ScriptName : Latin
InputMethodTips : {0809:00020409}
Spellchecking : True
Handwriting : False
PS > Set-WinUserLanguageList $langs -Force
Ghost keyboard bug
Even in Germany, I use English (United Kingdom)
as the system language and format. For some
unknown reason, Windows insists on adding the German keyboard to the keyboard list.
To make matters worse, it does not appear in Regedit
(Computer\HKEY_USERS\.DEFAULT\Keyboard Layout\Preload
) or in the language and region options.
It is necessary to manually add it just to be able to remove the German keyboard from the list.
This can also be done via PowerShell:
$langs = Get-WinUserLanguageList
$langs[0].InputMethodTips.Add('0809:00000407')
Set-WinUserLanguageList $langs -Force
$langs[0].InputMethodTips.Remove('0809:00000407')
Set-WinUserLanguageList $langs -Force
Check the code in Regedit
(Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Language
).
ID | Tag | Language | Location |
---|---|---|---|
0x0416 | pt-BR | Portuguese | Brazil |
0x0816 | pt-PT | Portuguese | Portugal |
0x0409 | en-US | English | United States |
0x0809 | en-GB | English | United Kingdom |
0x0c0A | es-ES | Spanish | Spain |
0x0407 | de-DE | German | Germany |
0x1000 | en-150 | English | Europe |
0x1000 | en-DE | English | Germany |
Complete table: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/a9eac961-e77d-41a6-90a5-ce1a8b0cdb9c
Additional Clock
I have been communicating a lot with people from Australia and Norway. Since the time zone is quite different, I like to have an additional clock.
Go to Date & Time » Add clocks for different time zones
and set up the new clock.
Customization
-
Wallpaper
In
Settings » Personalization
, choose a background. I usually set it to Solid color black. -
Colors
Default app mode: Dark
-
Lock screen
Disable showing apps on the lock screen and background on the sign-in screen.
-
Fonts
Install a Nerd Font.
I recommend Hack NF. Unzip the package, select all “Windows Compatible” fonts, right-click, and choose the Install or Install for all users option.Install Google Noto Fonts to avoid issues with unavailable characters (displayed as rectangles). Prefer the hinted version.
-
Show/Hide icons on the desktop
Themes » Desktop Icon Settings
. I like to keep This PC, Recycle Bin, and User folder. -
Taskbar
Remove all unnecessary items from the taskbar. Hide the search bar.
-
Disable programs that start with the system
Open the task manager and disable programs that start with the system.
-
File Explorer
Open File Explorer. Select
View » Options » Change folder and search options
. In the View tab, check/uncheck the following options:- Always show menus
- Display the full path in the title bar
- Show hidden files, folders, and drives
- Hide extensions for known file types
- Hide protected operating system files
-
Remove OneDrive from quick access
[HKEY_CLASSES_ROOT\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}] "System.IsPinnedToNameSpaceTree"=dword:00000000
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}] "System.IsPinnedToNameSpaceTree"=dword:00000000
-
Default Apps
- Music player: VLC
- Photo viewer: IrfanView
- Video player: VLC
- Web browser: Firefox
I also like to associate programs with extensions:
.txt
→ Notepad++
-
Chrome and Firefox
Sync the browsers. Copy extension settings like uMatrix, if you have it.
-
Swap Esc with CapsLock
It is possible to do it through Regedit, SharpKeys, PowerToys, and many others.
-
Regedit
Save the following code as
caps_swapescape.reg
and run it:Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout] "Scancode Map"=hex:00,00,00,00,00,00,00,00,03,00,00,00,3a,00,01,00,01,00,3a,00,00,00,00,00
A mapping consists of a 32-bit integer (two 16-bit scancodes each) in little-endian format.
(03,00,00,00)
→ Indicates that 3 integers will come (96 bits = 24 hex digits)(01,00)
→ Escape(3a,00)
→ CapsLock-
SharpKeys
Caps Lock (00_3A) → Escape (00_01) Escape (00_01) → Caps Lock (00_3A)
-
PowerToys Enable Keyboard Manager » remap a key
-
-
Desktops
Swipe up with four fingers on the touchpad to bring up the option to create new desktops. I like to use 2 desktops.
Terminal
I like Cmder and Windows Terminal (available in the Microsoft Store). They are highly customizable. An important change is setting the font. I recommend Hack NF.
In Terminal (settings.json):
…
"actions": [
{
"command": {
"action": "copy",
"singleLine": false
},
"keys": "ctrl+c"
},
{
"command": "paste",
"keys": "ctrl+shift+v"
},
{
"command": "find",
"keys": "ctrl+shift+f"
},
{
"command": {
"action": "splitPane",
"split": "auto",
"splitMode": "duplicate"
},
"keys": "alt+shift+d"
},
{
"command": {
"action": "sendInput",
"input": "\u001b[13;2u"
},
"keys": "shift+enter"
},
{
"command": {
"action": "sendInput",
"input": "\u001b[13;5u"
},
"keys": "ctrl+enter"
},
{
"command": {
"action": "sendInput",
"input": "\u001b[13;6u"
},
"keys": "ctrl+shift+enter"
},
{
"command": {
"action": "sendInput",
"input": "\u001b[32;2u"
},
"keys": "shift+space"
},
{
"command": {
"action": "sendInput",
"input": "\u001b[32;5u"
},
"keys": "ctrl+space"
},
{
"command": {
"action": "sendInput",
"input": "\u001b[32;6u"
},
"keys": "ctrl+shift+space"
}
]
…
"defaultProfile": "{2c4de342-38b7-51cf-b940-2309a097f518}",
…
{
"guid": "{2c4de342-38b7-51cf-b940-2309a097f518}",
"hidden": false,
"name": "Ubuntu",
"fontFace": "Hack NF",
"source": "Windows.Terminal.Wsl"
},
…
{
"guid": "{574e775e-4f2a-5b96-ac1e-a2962a402336}",
"hidden": false,
"name": "PowerShell",
"fontFace": "Hack NF",
"source": "Windows.Terminal.PowershellCore"
}
I change the paste
command from ctrl+v
to ctrl+shift+v
to avoid breaking visual mode in vim.
Sandbox
For application testing, especially from dubious sources, it is recommended to use an isolated system: sandboxes or virtual machines.
For cases where it is not necessary or desirable to persist installations and configurations and the current version of Windows works, a sandbox is more practical than VMs. You don’t need to download images, it opens faster, takes up less disk space, etc.
Sandboxing can be done with programs like Sandboxie, however, Windows 10 Professional already comes with this feature natively, just needs to be activated.
The setup is very simple and the performance is good. Windows Sandbox uses Windows Containers technology, which in turn uses Hyper-V.
The Sandbox can be activated in Windows Features or with the following command in PowerShell:
Enable-WindowsOptionalFeature -Online -FeatureName "Containers-DisposableClientVM"
The configuration is done via XML files with the extension .wsb
, like the following:
<Configuration>
<VGpu>Disable</VGpu>
<Networking>Disable</Networking>
<MappedFolders>
<MappedFolder>
<HostFolder>C:\Share</HostFolder>
<SandboxFolder>C:\Share</SandboxFolder>
<ReadOnly>true</ReadOnly>
</MappedFolder>
</MappedFolders>
<AudioInput>Disable</AudioInput>
<VideoInput>Disable</VideoInput>
<ProtectedClient>Enable</ProtectedClient>
<PrinterRedirection>Disable</PrinterRedirection>
<ClipboardRedirection>Disable</ClipboardRedirection>
<MemoryInMB>8192</MemoryInMB>
<LogonCommand>
<Command>explorer.exe C:\Share</Command>
</LogonCommand>
</Configuration>
This example starts a sandbox in protected mode, with 8 GB of RAM, read access to the C:\Share
folder, and no access to network, microphone, webcam, printer, or desktop.
Virtualization: Hyper-V
Microsoft Sandbox is great for quick tests and running portable applications, but it does not cover the use case where persisting system modifications is necessary. In these cases, we should use virtual machines.
If you have a powerful server, it may be worth installing a virtual machine manager like Proxmox VE and using VMs for remote access. Depending on the situation, deploying a VM in the cloud is also a good idea.
For local installations on Windows, there are several hypervisor options, which can be of two types:
- Type 1 Hypervisor:
- Bare-metal, native
- Accesses hardware directly
- Better performance
- Examples: VMware ESXi (VMware vSphere), Microsoft Hyper-V, Oracle VM, Citrix Hypervisor
- Type 2 Hypervisor:
- Hosted
- Runs on the operating system
- Easier to manage
- Examples: VMware Fusion, VMware Workstation Pro, Oracle VM VirtualBox
VMware is said to have the most features, but I have been using Hyper-V that comes with Windows Pro mainly due to cost.
Linux, FreeBSD, and Windows can be installed on Hyper-V. One detail is that virtualized Windows also requires a license.
Tips:
- Prefer using Generation 2.
- Enable TPM: Security » Enable Trusted Platform Module
- Create checkpoints (snapshots) before any changes
- Offline installation (Windows 11):
- Press Shift+F10 to open the terminal
- Run C:\Windows\System32\oobe\BypassNRO.cmd
- Click “I don’t have internet”
- Click “Continue with limited setup”
- In enhanced session mode, it is possible to copy and paste files between host and VM
- Virtual disks “.vhdx” can be mounted to share files. Remember to unmount them before starting the VMs.
- Activate Guest services
Nvidia Graphics Card on Hyper-V
Updated in Jan/2023. Using Windows 11.
Due to a security issue, Microsoft has disabled the “RemoteFX vGPU” option that allowed multiple VMs to share a GPU.
In Windows Server, there is an option to allocate a GPU entirely to a VM, known as GPU passthrough via Discrete Device Assignment (DDA). However, only Enterprise GPUs like Nvidia Quadro work with this feature.
The current solution is GPU Paravirtualization
/GPU Partitioning
. Refer to the following links
for more information:
- Easy-GPU-PV: https://github.com/jamesstringerparsec/Easy-GPU-PV
- https://www.youtube.com/watch?v=XLLcc29EZ_8
Get-VMHostPartitionableGpu
WSL2
After enabling “Windows Subsystem for Linux” in Windows Features, additional configuration is required.
Tip: much of what I wrote in the article about Arch also applies to Ubuntu on WSL.
-
Install the kernel update
-
Update WSL, if necessary
wsl --update
-
Set WSL2 as default:
wsl --set-default-version 2
-
Install Ubuntu
-
Option 1: from the Microsoft Store
-
Option 2: via command line
cd ~\Downloads curl.exe -L -o ubuntu-2204.appx https://aka.ms/wslubuntu2204 Add-AppxPackage .\ubuntu-2204.appx
Run the file
~\Downloads\ubuntu-2204.appx
. A message will appear stating that Ubuntu is already installed and alaunch
button to start Ubuntu.
-
-
Check if the WSL version is 2:
wsl --list --verbose
If your version is 1, run
wsl --set-version Ubuntu 2
. -
[Optional] Move the image from C: to Z:
VHDs (virtual hard disks) in WSL2 are saved in
C:\Users\[user]\AppData\Local\Packages\[distro]\LocalState\[distroPackageName]
. Example:
C:\Users\Julio\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\ext4.vhdx
.
It is possible to move the image and redirect the path through Regedit, but there is a safer way using the function to export and import images:
Z:
mkdir Z:\WSL
wsl --export Ubuntu Z:\WSL\Ubuntu.tar
wsl --unregister Ubuntu
wsl --import Ubuntu Z:\WSL\ Z:\WSL\Ubuntu.tar
ubuntu.exe config --default-user julio
rm Z:\WSL\Ubuntu.tar
-
Adjust the locales
sudo nvim /etc/locale.gen sudo locale-gen
-
Do not add Windows folders to the $PATH
Add the following lines to the file
/etc/wsl.conf
:[interop] appendWindowsPath = false
This significantly improves autocomplete performance on the command line, as accessing the Windows file system is very time-consuming.
It is still possible to start programs from WSL, just use the full path or add symlinks in a folder that is already in the $PATH.
See https://learn.microsoft.com/en-us/windows/wsl/wsl-config#interop-settings
-
Enable Systemd
Some programs (Snap, Flatpak, microk8s) depend on Systemd.
Add the following lines to the file /etc/wsl.conf
:
[boot]
systemd=true
Restart WSL: wsl.exe --shutdown
.
-
Configure memory
WSL2 runs on Hyper-V. By default, half (or 80% in new builds) of the machine’s memory is allocated. This value can be changed in the file
C:\Users\julio\.wslconfig
:wsl --shutdown notepad "$env:USERPROFILE/.wslconfig"
[wsl2] memory=16GB swap=0 processors=4
Check with the
free
command in Linux.Notes:
- Do not set a very high value, as what is allocated to Linux cannot be used by Windows.
- To release memory, run
echo 1 >> /proc/sys/vm/drop_caches
as root. - The
.wslconfig
file must be saved as UTF-8 without BOM. - The swap is saved in
%USERPROFILE%\AppData\Local\Temp\swap.vhdx
-
Add additional repositories (PPAs):
PPAs (Personal Package Archive) are additional repositories to Ubuntu’s repositories. Many of them are from official maintainers.
- Neovim:
sudo add-apt-repository ppa:neovim-ppa/unstable sudo apt update
- Git
sudo add-apt-repository ppa:git-core/ppa sudo apt update
-
Update the system
sudo apt update && sudo apt upgrade
-
Install programs available via repositories:
Basics:
sudo apt install \ ack \ curl \ ffmpeg \ git \ gitk\ jq \ make \ neovim \ p7zip-full \ renameutils \ rsync \ sshfs \ tree \ wget \ zsh \ oathtool
LaTeX:
sudo apt install \ latexmk \ texlive-lang-portuguese \ texlive-xetex
Dependencies to compile Python:
sudo apt install \ build-essential \ libbz2-dev \ libffi-dev \ liblzma-dev \ libncursesw5-dev \ libreadline-dev \ libsqlite3-dev \ libssl-dev \ libxml2-dev \ libxmlsec1-dev \ llvm \ tk-dev \ xz-utils \ zlib1g-dev
-
Clone dotfiles (https://github.com/jbsilva/dotfiles) and create links to configuration files
cd ~ ln -s dotfiles/.zsh ln -s dotfiles/.zshrc ln -s dotfiles/.gitconfig-global ln -s dotfiles/.gitconfig-wsl .gitconfig ln -s dotfiles/.p10k.zsh ln -s dotfiles/.config
-
Install programs from other sources:
The Ubuntu repository does not always have the latest versions of packages. Alternatives:
- PPAs
- Snap
- Flatpak
- Appimage
.deb
packages- Pre-compiled executables
- Asdf
- Cargo
- Compile source code
Asdf:
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.13.1
Mambaforge:
wget https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh bash Mambaforge-Linux-x86_64.sh
Flatpak (enable Systemd first):
sudo apt install flatpak gnome-software-plugin-flatpak gnome-software
flatpak remote-add --if-not-exists --user flathub https://flathub.org/repo/flathub.flatpakrepo
flatpak update
Hugo:
CGO_ENABLED=1 go install --tags extended github.com/gohugoio/hugo@latest
or
HUGO_LATEST="0.121.1" wget -qO- https://github.com/gohugoio/hugo/releases/download/v${HUGO_LATEST}/hugo_extended_${HUGO_LATEST}_linux-amd64.tar.gz | tar xvz hugo -C ~/bin/
or
asdf plugin add hugo HUGO_LATEST=$(asdf list-all hugo | tail -1) asdf install hugo extended_$HUGO_LATEST asdf global hugo extended_$HUGO_LATEST
Zellij:
ZELLIJ_LATEST=0.39.2 wget -qO- https://github.com/zellij-org/zellij/releases/download/v${ZELLIJ_LATEST}/zellij-x86_64-unknown-linux-musl.tar.gz | tar xvz zellij -C ~/bin/
Yt-dlp:
python -m pip install -U --pre yt-dlp
or
mkdir -p ~/bin wget -O ~/bin/yt-dlp https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_linux yt-dlp --update-to nightly
ExifTool:
ExifTool is a very useful program to keep my photo library organized.
mkdir -p ~/bin EXIFTOOL_LATEST=12.70 wget -qO- https://exiftool.org/Image-ExifTool-${EXIFTOOL_LATEST}.tar.gz | tar xvzf - -C ~/bin/ mv ~/bin/Image-ExifTool* ~/bin/ExifTool ln -s ~/bin/ExifTool/exiftool ~/bin/exiftool
-
Set default shell:
chsh -s $(which zsh)
Compress WSL2 image
Compressing the image can save some MBs.
-
In WSL2:
# apt autoremove && apt autoclean && apt clean # fstrim /
-
In PowerShell:
> Get-AppxPackage -Name "*Ubuntu*" | Select PackageFamilyName PackageFamilyName ----------------- CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc
> wsl --shutdown > optimize-vhd -Path "C:\Users\Julio\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\ext4.vhdx" -Mode full
X server
Install VcXsrv and allow it through the firewall (Windows Defender). Check the option Disable access control.
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2; exit;}'):0.0
Note: the best way to make clipboard work in Neovim is with win32yank.exe. It is installed along with Neovim for Windows, but can also be installed manually:
mkdir ~/bin
export PATH=$HOME/bin:$PATH
wget https://github.com/equalsraf/win32yank/releases/latest/download/win32yank-x64.zip
unzip -p win32yank-x64.zip win32yank.exe > ~/bin/win32yank.exe
chmod +x ~/bin/win32yank.exe
rm -f win32yank-x64.zip
Copy to the +
register using "+y
. Alternatively, use :set clipboard=unnamedplus
in Neovim.
Docker Desktop with WSL2
This option is the simplest, but only free for personal, academic, open-source, or small business use (less than 250 employees AND less than $10 million in annual revenue).
Download Docker Desktop (I download it through Chocolatey). Check the options
Use the WSL 2 based engine
and Expose daemon on tcp://localhost:2375 without TLS
.
This is enough to use Docker normally in the Ubuntu terminal.
Docker with WSL2 without Docker Desktop
Docker Desktop is paid for use in large companies, however, it is not necessary to run Docker.
There are multiple alternatives:
- Install Docker directly in the WSL2 distro (with Systemd or containerd)
- Podman
- Rancher Desktop
Docker in WSL2 with Systemd
In another part of this article, I explain how to enable Systemd by editing the file
/etc/wsl.conf
.
-
Remove old packages
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
rm ~/.docker/config.json
-
Add the official Docker
apt
repository# Adiciona a chave GPG oficial do Docker sudo apt update sudo apt install ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Adiciona o repositório apt à lista echo \ "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
-
Install Docker and the docker-compose-plugin
sudo apt update && \ sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Update: the docker-compose v1 is the old Python version, without updates since May 2021. The plugin was rewritten in Go and its command is now
docker compose
(with a space instead of a hyphen). -
Optionally, add your user to the
docker
group to avoid usingsudo
:sudo usermod -aG docker $USER
See possible updates in the official documentation.
Be aware that this could be a security loophole.
-
Test the installation
sudo docker run hello-world
Docker with Rancher Desktop
Rancher is a good replacement for Docker Desktop, especially for Kubernetes. It can be installed via Chocolatey:
choco install rancher-desktop
NVIDIA Container Toolkit
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
&& curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt update && sudo apt install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
$ cat /etc/docker/daemon.json
{
"runtimes": {
"nvidia": {
"args": [],
"path": "nvidia-container-runtime"
}
}
}
sudo systemctl restart docker
Test with the following command:
docker run --gpus all nvcr.io/nvidia/k8s/cuda-sample:nbody nbody -gpu -benchmark
Visual Studio Code with WSL2
VS Code installed on Windows has native integration with WSL2. You will need to install the extensions in WSL2 as well.
GUI for Git
Using Git through the command line is excellent for almost everything, but some tasks are easier to perform visually.
Tools installed on Windows may suffer from performance issues when accessing the WSL file system, so I recommend installing them directly on Linux. This eliminates some GUIs like Sourcetree.
The tools I have tested and liked are:
-
- It already comes with a good version control tool. Some extensions offer more functionalities, but I don’t use them.
-
- It was the first GUI for Git. I use it a lot to view changes in a single file.
-
- It is very comprehensive and visually appealing, but it is a paid tool.
sudo apt update sudo apt install -y libgbm-dev libnotify4 wget https://release.gitkraken.com/linux/gitkraken-amd64.deb sudo dpkg -i ./gitkraken-amd64.deb sudo apt install -f
-
-
Through Flatpak:
$ flatpak search gittyup Name Description Application ID Version Branch Remotes Gittyup Graphical Git client com.github.Murmele.Gittyup v1.3.0 stable flathub
flatpak install flathub com.github.Murmele.Gittyup
-
flatpak run --nosocket=fallback-x11 --socket=x11 com.github.Murmele.Gittyup
- AppImage:
wget -q -O ~/bin/gittyup \
$(wget -q -O - https://api.github.com/repos/Murmele/Gittyup/releases | \
jq -r '.[0].assets[] | select(.name | test("^Gittyup.*AppImage$")) | .browser_download_url') && \
chmod +x ~/bin/gittyup && \
gittyup --version
AWS CLI
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
or with asdf
:
asdf plugin add awscli
asdf install awscli latest
asdf global awscli latest
Access via SSH
WSL2 is a virtual machine with its own IP address.
This address can be found in the following ways:
- Install OpenSSH
sudo apt install openssh-server
- Adjust settings in
/etc/ssh/sshd_config
Port 2255
ListenAddress 0.0.0.0
PasswordAuthentication yes
- Discover the VM’s IP address
Using iproute2 in WLS2:
$ ip addr show eth0
…
inet 172.21.145.176/20 brd 172.21.159.255 scope global eth0
…
Or, through PowerShell:
$ wsl -- ip -o -4 -j addr s eth0 | ConvertFrom-Json | %{ $_.addr_info.local } | ?{ $_ }
172.21.145.176
Note: the value in /etc/resolv.conf
is the host’s address, not the VM’s.
$wsl = wsl -- ip -o -4 -j addr s eth0 | ConvertFrom-Json | %{ $_.addr_info.local } | ?{ $_ }
$host = (Get-NetIPAddress).IPAddress | ?{ $_ -match ($wsl -replace '^((\d+\.){2}).*$','^$1') }
$wsl,$host
- Check if the service is running
Read the section above on how to enable Systemd first.
$ sudo systemctl status sshd.service
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled)
Active: active (running) since…
- Create a portproxy between the VM and the Host
In an admin PowerShell:
netsh interface portproxy add v4tov4 listenport=2255 listenaddress=0.0.0.0 connectport=2255 connectaddress=172.21.145.176
- Allow port 2255 in the Firewall
netsh advfirewall firewall add rule name="Open Port 2255 for WSL2" dir=in action=allow protocol=TCP localport=2255
$ netsh interface portproxy show v4tov4
Listen on ipv4: Connect to ipv4:
Address Port Address Port
--------------- ---------- --------------- ----------
0.0.0.0 2255 172.21.145.176 2255
Scanner
There are many programs to interact with the scanner, but the best one I know is XSane, which is a frontend for SANE.
sudo apt install xsane
I have a Canon Pixma MG5450 multifunction printer. The full name does not appear on the compatible devices page, but it is part of the “PIXMA MG5400 Series”, which is included in the sane-pixma backend.
The command scanimage -L
broadcasts to detect connected scanners. By default, Canon devices can be
discovered using the BJNP protocol on UDP port 8612.
Unfortunately, this command did not detect my scanner at first.
I knew it was not a connection error because curl http://192.168.15.7
returns the printer’s page
(this IP is fixed on my DHCP server).
The solution was to explicitly state the printer’s IP in the pixma.conf
file:
echo "bjnp://192.168.15.7" | sudo tee -a /etc/sane.d/pixma.conf
The command worked without issues after that:
$ scanimage -L
device `pixma:MG5400_192.168.15.7' is a CANON Canon PIXMA MG5400 Series multi-function peripheral
The --all
parameter lists possible options compatible with the backend used:
$ scanimage --device "pixma:MG5400_192.168.15.7" --all
Output format is not set, using pnm as a default.
All options specific to device `pixma:MG5400_192.168.15.7':
Scan mode:
--resolution auto||75|150|300|600|1200|2400dpi [75]
Sets the resolution of the scanned image.
--mode auto|Color|Gray|Lineart [Color]
Selects the scan mode (e.g., lineart, monochrome, or color).
--source Flatbed [Flatbed]
Selects the scan source (such as a document-feeder). Set source before
mode and resolution. Resets mode and resolution to auto values.
…
This way, I could scan a document at 150 dpi directly from the command line using scanimage:
scanimage \
--device "pixma:MG5400_192.168.15.7" \
--format=png \
--output-file scan.png \
--resolution 150 \
--progress
However, it’s much easier with XSane.
Audio
Programs like Virtual Audio Cable and Voicemeeter are useful for configurations with multiple speakers and for streaming. The free versions of both can be installed via Chocolatey.
- Go to
Control Panel\Hardware and Sound » Sound
; - Under Playback, set VoiceMeeter Input as the default device and VoiceMeeter Aux Input as the default communication device;
- In
Recording
, set VoiceMeeter Output as the default device and VoiceMeeter Aux Output as the default communication device; - Go to the
Advanced
tab in the properties of each device and set the sample rate (e.g., 24 bit, 48000 Hz). The sample rate should be set to the same value in Voicemeeter (in Menu » System settings » Preferred Main SampleRate). - Example configuration for Voicemeeter Banana:
- Hardware Input 1: Notebook microphone
- Hardware Input 2: Headset microphone
- Hardware Input 3: CABLE Output (VB-Audio Virtual Cable)
- Voicemeeter VAIO: Desktop Output » A1, B1
- Voicemeeter AUX: Calls Output » A1
- A1: WDM: Speakers / Headphones
- A2: WDM: Headset
- A3: WDM: TV connected via HDMI
-
Note 1: I only set up my Bluetooth headset microphone when I use it, as it saves energy and I can use the headphones in high-quality sound mode.
-
Note 2: I had an issue with Spotify after installing Voicemeeter. I solved it by reinstalling Spotify.
Another very useful program is EarTrumpet. It allows you to set, for each program, which audio output to use and at what volume.
Streaming
For video calls where I want to share the sound being played on the computer in addition to my microphone, but without the sound from the call itself (other participants’ voices):
- In Meets/Teams/Discord/Skype:
- Microphone: VoiceMeeter Output
- Speaker: VoiceMeeter Aux Input
- In VoiceMeeter:
- Mic PC: B1
- Desktop (Voicemeeter VAIO): A1, B1
- Calls (Voicemeeter AUX): A1
Links
- https://github.com/bitsadmin/winconfig/tree/master/CleanWindows
- https://www.dedoimedo.com/computers/windows-10-essential-post-install-tweaks.html
- https://nickymeuleman.netlify.app/blog/linux-on-windows-wsl2-zsh-docker
- https://github.com/neovim/neovim/wiki/FAQ#how-to-use-the-windows-clipboard-from-wsl
- https://vb-audio.com/Voicemeeter/VoicemeeterBanana_UserManual.pdf
- https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-sandbox/windows-sandbox-configure-using-wsb-file
- https://aka.ms/wslsystemd
- https://learn.microsoft.com/en-us/windows/wsl/wsl-config
- https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html