Search notes:

After installing Windows

These are some notes where I try to gather scripts that configure a newly installed Windows system so that I feel comfortable using it.

Check what's already installed

Take a quick look at

Change execution policy of PowerShell

In order to be able to run PowerShell scripts, the execution policy for PowerShell needs to be changed.
Without changing this policy, trying to execute a script results in the error message: script cannot be loaded because running scripts is disabled on this system.
The current value of the execution policy is found in the registry key HKEY_CURRENT_USER\Software\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell (value ExecutionPolicy). This value should be set to RemoteSigned.
Interestingly, PowerShell provides the set-executionPolicy cmdlet that does exactly that:
set-executionPolicy remoteSigned -scope currentUser -force
2019-04-01 it turned out that the mentioned key does not exist after a fresh installation of Windows - but it is created with the cmdLet.
2020-03-09 On a Windows 7 (PowerShell 2.0) installation, the option removeSigned was not understood. I had to change it to bypass.

Activate webRequest-invoke

invoke-webRequest throws the error message
invoke-webrequest : The response content cannot be parsed because the Internet Explorer engine is not available, or Internet Explorer's first-launch configuration is not complete.
Specify the UseBasicParsing parameter and try again.
What needs to be done in order for webRequest-invoke to work? Does it have anything to do with the -useBasicParsing option of invoke-webRequest?
It seems that this behavior can be controlled with the registry value DisableFirstRunCustomize, found under the registry key HKLM|HKCU\Software\Policies\Microsoft\Internet Explorer.

Install/Copy PowerShell profile

Install the profile script profile.ps to $profile.

Check hostname

Is hostname ok?
PS:\> hostname

Start PowerShell as administrator

If a PowerShell is needed with administrator privileges, the start-process cmdlet can be used:
start-process powershell -verb runAs
2021-08-10 The admin.ps1 script can now be used to become admininstrator or to query if I am already running as administrator.

Activate Windows

Check current license state and, if available, expiration date:
PS C:\users\rene> cscript -nologo $env:windir\system32\slmgr.vbs -xpr
Windows(R), Professional edition:
    Windows is in Notification mode
Uninstall previous product key
PS C:\users\rene> cscript -nologo $env:windir\system32\slmgr.vbs -upk
Uninstalled product key successfully.
Activate new product key
PS C:\users\rene> cscript -nologo $env:windir\system32\slmgr.vbs -ipk xxxxx-xxxxx-xxxxx-xxxxx-xxxxx
Installed product key xxxxx-xxxxx-xxxxx-xxxxx-xxxxx successfully.
In a previous attempt to execute this command, Settings->Activation told me: A known error with Windows activation is: We can't activate Windows on this device as we can't connect to your organization's activation server. (or something similar to that). So, I had also to enter the following to fix that:
… slmgr.vbs /dlv
Check current license state again
PS C:\users\rene> cscript -nologo $env:windir\system32\slmgr.vbs -xpr
    The machine is permanently activated.

TODO

Does slmgr.vbs have something to do with changepk.exe or slui.exe (under %SYSTEMROOT%\System32)?

Change default keyboard layout

Capslock needs to be swapped with ESC, the right Windows key needs to function as control key: Use this PowerShell script to change the registry accordingly (requires administrator privileges).
If adminstrator privileges are not available, try to compile swap_keys.c or use the C-Sharp program SwapKeys.cs.

Configure Text Services and Input Methods

Language list

A language list can be created with the winUserLanguageList cmdLet noun:
$preferredLanguages = new-winUserLanguageList 'en-US'
$preferredLanguages.add('de-CH')
set-winUserLanguageList -force $preferredLanguages

Windows 11

2024-03-29: In Windows 11, I had the problem that months after executing these command a third item appeared in the language bar: Swissgerman with US Keyboard.
Unfortunately, I was unable to get rid of the third item by running the Powershell commands again.
It seemd to finally disappear by going to Settings -> Time & language -> Language & region -> Choosing «deutsch» in Windows display language and the remove the US keyboard from there - but only to be completely messed up aftwards.

Registry

Before I knew that there were PowerShell cmdLets like new-winUserLanguageList and set-winUserLanguageList, I tried to configure the language list directly in the registry.
#
# No substitutes
#    Remove entire key 'HKCU\Keyboard Layout\Substitutes' and add an empty one
#
  remove-item        -path 'HKCU:\Keyboard Layout\Substitutes'
  $eatMe = new-item  -path 'HKCU:\Keyboard Layout\Substitutes'

#
# Remove HKCU\Keyboard Laoyout\Preload
#   Strangly, this remove-item does not seem to entirely remove
#   the specified key:
#
  remove-item        -path 'HKCU:\Keyboard Layout\Preload'

#
# Add US and Swiss German keyboard layouts
#
  new-itemProperty -path 'HKCU:\Keyboard Layout\Preload' -name  1 -value ('0000' + '0409') # US
  new-itemProperty -path 'HKCU:\Keyboard Layout\Preload' -name  2 -value ('0000' + '0807') # German (Switzerland)

Language bar

#
# Language Bar
#
  $null = new-itemProperty -path 'HKCU:\Software\Microsoft\CTF\LangBar' -name  ShowStatus             -value 4  -propertyType DWord -force   # Docked in the Taskbar
  $null = new-itemProperty -path 'HKCU:\Software\Microsoft\CTF\LangBar' -name  Label                  -value 1  -propertyType DWord -force   # Show text labels on the Language Bar
  $null = new-itemProperty -path 'HKCU:\Software\Microsoft\CTF\LangBar' -name  ExtraIconsOnMinimized  -value 0  -propertyType DWord -force   # Don't »Show additional Language bar icons in the taskbar«
See also showing the language bar again after it has disappeared from the Taskbar.

Hotkeys to switch between keyboard layouts

#
# Hotkeys to switch between keyboard layouts
#

  $mod_leftAlt = 0x01
  $VK_0        = 0x30
  $VK_9        = 0x39

  $valKeyModifiers      = [byte[]]( $mod_leftAlt , 0xc0 , 0x00 , 0x00 )
  $valLayoutUS          = [byte[]](         0x09 , 0x04 , 0x09 , 0x04 )
  $valLayoutSwissGerman = [byte[]](         0x07 , 0x08 , 0x07 , 0x08 )
  $valVK_0              = [byte[]](        $VK_0 , 0x00 , 0x00 , 0x00 )
  $valVK_9              = [byte[]](        $VK_9 , 0x00 , 0x00 , 0x00 )
 
  remove-item        -path 'HKCU:\Control Panel\Input Method\Hot Keys\00000100'
  remove-item        -path 'HKCU:\Control Panel\Input Method\Hot Keys\00000101'
  $eatMe = new-item  -path 'HKCU:\Control Panel\Input Method\Hot Keys\00000100'
  $eatMe = new-item  -path 'HKCU:\Control Panel\Input Method\Hot Keys\00000101'

  $eatMe = new-itemProperty -path 'HKCU:\Control Panel\Input Method\Hot Keys\00000100' -name 'Virtual Key'   -value $valVK_9                 -propertyType binary
  $eatMe = new-itemProperty -path 'HKCU:\Control Panel\Input Method\Hot Keys\00000100' -name 'Key Modifiers' -value $valKeyModifiers         -propertyType binary
  $eatMe = new-itemProperty -path 'HKCU:\Control Panel\Input Method\Hot Keys\00000100' -name 'Target IME'    -value $valLayoutUS             -propertyType binary

  $eatMe = new-itemProperty -path 'HKCU:\Control Panel\Input Method\Hot Keys\00000101' -name 'Virtual Key'   -value $valVK_0                 -propertyType binary
  $eatMe = new-itemProperty -path 'HKCU:\Control Panel\Input Method\Hot Keys\00000101' -name 'Key Modifiers' -value $valKeyModifiers         -propertyType binary
  $eatMe = new-itemProperty -path 'HKCU:\Control Panel\Input Method\Hot Keys\00000101' -name 'Target IME'    -value $valLayoutSwissGerman    -propertyType binary

Registry links

TODO

What is the relationship to the PowerShell cmdlets
set-culture             en-GB
set-winSystemLocale     en-GB
set-winUserLanguageList en-GB
set-winHomeLocation -geoId 242
Check the values under the registry key HKEY_CURRENT_USER\Control Panel\International\User Profile, especially the value of Languages.
Should Windows be put into developer mode?

Check default values in registry

HKEY_LOCAL_MACHINE\SOFTWARE\RegisteredApplications

Change mouse speed

PowerShell: modify the speed of the mouse

Install Chocolatey

Install chocolatey

Software that can be installed with Chocolatey

Software that I feel should be installed on my computer that can be installed with Chocolatey include

File Explorer

Show hidden files and file extensions in explorer.exe.
In order for this change to take effect, explorer needs to be restarted.
Configure Quick Access

Edge

Don't show tabs when Alt-tabbing

Set MultiTaskingAltTabFilter under HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced to 3 so that Edge's tabs are not shown when alt-tabbing through programs.

Change the AcceptLanguage for Edge in the browser

In order to make it easier to download english software (because some «clever» sites almost force me to download their software in the language of the browser), the AcceptLanguage HTTP header should be changed under HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\International.

Create variables, functions etc for installation

$downloadFolder = "$home\Downloads\"
$binPath        = "$home\bin"

$ua = new-object System.Net.WebClient
[net.servicePointManager]::securityProtocol = [net.securityProtocolType]::Tls12

$shell = new-object -comObject shell.application

Download folder ($downloadFolder)

Stuff to be downloaded might go into the Downloads directory.
The location of the download directory can be determined with the WinAPI function SHGetKnownFolderPath.
In PowerShell, this function can be accessed by running this P/Invoke class. After running the linked script, the download folder name can be assigned to a variable with
PS C:\> $downloadFolder = $([shell32]::GetKnownFolderPath('{374DE290-123F-4565-9164-39C4925E467B}'))
It seems easier, however, to directly set the variable to $home\Downloads\.

Function addDirToPath

A function to add directories to the PATH environment variable.
Because the change in the registry does not take immediate effect, the function also modifes the variable directly.
function addDirToPath($dir) {
   $userPath   = [environment]::getEnvironmentVariable('PATH', 'user'   )
   $systemPath = [environment]::getEnvironmentVariable('PATH', 'machine')

   [environment]::setEnvironmentVariable('PATH', "$dir;$userPath", 'user')
   $env:PATH = "$systemPath;$dir;$userPath"
}

Create bin directory

Create a bin directory under %UserProfile% to store executables and scripts so that they can be called from the command line (such as cmd.exe or PowerShell).
With PowerShell:
$null = mkdir $binPath -errorAction silentlyContinue
Add the newly created directory to the PATH environment variable:
# $userPath = [environment]::getEnvironmentVariable("PATH", "user")
# [environment]::setEnvironmentVariable("PATH", "$binPath;$userPath", 'user') 
addDirToPath $binPath

User Agent ($ua)

$ua «stores» a User Agent which is required to download files from the internet.
Setting securityProtocol to Tls12 prevents the error: The request was aborted: Could not create SSL/TLS secure channel.

Add or modify additional environment variables

PATHEXT

In order for PowerShell to run a script (such as Perl or Python script) in the current console (rather than opening another one), the script's extension must be listed in the PATHEXT environment variable.

Github, Git and notes related variables

Add the environment variables github_top_root and github_root
set-environmentVariable github_top_root $home\github\
set-environmentVariable github_root     $home\github\github\
set-environmentVariable git_work_dir    $home\localgit\
set-environmentVariable rn_root         $home\renenyffenegger.ch\
Because the change does not take effect in the current session, the variables also need to be set manually:
$env:github_top_root = "$home\github\"
$env:github_root     = "$home\github\github\"
$env:git_work_dir    = "$home\localgit\"

PSModulePath

function add-psModulePath {

   param (
      [string] $psModulePath
   )

   if (! (test-path -pathType container $psModulePath)) {
      write-host "$psModulePath is not a directory"
      return
   }

   $psmodules = [environment]::getEnvironmentVariable('PSModulePath', 'user') -split ';'
   # $psmodules = @("${env:github_top_root}ps\modules") + $psmodules
   if ($psModules) {
      $psmodules = @($psModulePath) + $psmodules
   }
   else {
      $psmodules = @($psModulePath)
   }
   [environment]::setEnvironmentVariable('PSModulePath', ($psmodules -join ';') , 'user')
}
add-psModulePath "$env:github_top_root\ps\modules"

Change date format etc.

Date formats etc. are stored in the registry under the key HKEY_CURRENT_USER\Control Panel\International.

Install a non-edge browser

Chrome

As per this superuser answer, Chrome can be silently installed by downloading the Downloading the chrome installer and then useing the following switches:
chrome_installer.exe /silent /install
Alternatively, it seems it can be installed from an elevated command shell with Chocolatey with
choco install googlechrome

Firefox

Configure Firefox

Create a Profile folder with a fixed name:
Make the profiles.ini file point to this fixed profile filder by copying the following into %APPDATA%\Mozilla\Firefox\profiles.ini:
[General]
StartWithLastProfile=1

[Profile0]
Name=default
IsRelative=1
Path=Profiles/tq84
Default=1
TODO: This might also be achieved by using the -CreateProfile command line option of FireFox.

Configure Firefox - Addons

Install addons from command line says to
  • Download XPI (=zip) archive
  • Find UID in archive
  • Extract XPI to extensions\UID directory (under profile directory)
Does user.js need to contain something like:
user_pref("extensions.autoDisableScopes", 14);
vimium
Install Vimium-FF (and compare with vimium).
#
#  1 - Download xpi archive (and rename to zip in one go)
#
$ua = new-object system.net.webClient

# mkdir "$env:appdata\Mozilla\Firefox\Profiles\tq84\{EC8030F7-C20A-464F-9B0E-13A3A9E97384}"
  mkdir "$env:appdata\Mozilla\Firefox\Extensions\{EC8030F7-C20A-464F-9B0E-13A3A9E97384}"

# $ua.downloadFile("https://addons.mozilla.org/firefox/downloads/file/1192087", "$env:appdata\Mozilla\Firefox\Profiles\tq84\\{d7742d87-e61d-4b78-b8a1-b469842139fa}.xpi")
  $ua.downloadFile("https://addons.mozilla.org/firefox/downloads/file/1192087", "$env:appdata\Mozilla\Extensions\{EC8030F7-C20A-464F-9B0E-13A3A9E97384}\{d7742d87-e61d-4b78-b8a1-b469842139fa}.xpi")
# $ua.downloadFile("https://addons.mozilla.org/firefox/downloads/file/1192087/vimium_ff-1.64.3-fx.xpi" , "$env:appdata\Mozilla\Firefox\Profiles\tq84\{d7742d87-e61d-4b78-b8a1-b469842139fa}.xpi"
)

#
#   2- Unzip xpi archive
#
# $shell = new-object -comObject shell.application
mkdir $env:temp\vimium
$shell.nameSpace("$env:temp\vimium").copyHere($shell.nameSpace("$env:temp\vimium.zip").items())
UserAgent Switcher
Download xpi
Add blocker

Download Sysinternal tools

Download interesting Sysinternals tools and accept their EULA.
2019-03-02: It turns out that at least Procmon comes with the command line option /AcceptEula which does that, too.
2020-10-03: Sysinternals tools can off course also be installed with Chocolatey.

Install the WDK

Install the WDK so that interesting tools such as devcon.exe or usbview.exe are available.

Enable telnet feature

telnet.exe is apparently an optional feature («telnetClient») that needs to be enabled to be run. This is possible in an elevated PowerShell prompt:
enable-windowsOptionalFeature -featureName telnetClient -online

Activate Administrator account

Check current accounts (wmic useraccount) and HKEY_USERS
What about lusrmgr.msc
Check if Administrator is already activated:
net user administrator | findstr /c:"Account active"
In cmd.exe.
C:\> wmic useraccount where (name='administrator' and domain='%computername%') get name,sid
Activate and/or enable the administrator account and assign a password
c:\> net user administrator MYSECRETPASSWORD /active:yes
Apparently, this changes byte 0x38 in the value of V in the registry key in HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users\000001F4.
In PowerShell, the current adminstrator password status can apparently be determined like so:
$computerInfo = get-cimInstance win32_computerSystem

switch ( $computerInfo.adminPasswordStatus ) {
  0        { 'disabled'            }
  1        { 'enabled'             }
  2        { 'not implemented'     }
  3        { 'unknown'             }
  default  { 'unable to determine' }
}

Download a utility to change file type associations on the command line

In order to be able to change file type associations (FTAs) on the command line, a utility is needed. Such a functionality is provided by PowerShell script PS-SFTA.
PS:> set-FTA applications\code.exe .sql

SetUserFTA.exe

Another utility is SetUserFTA.exe which can be downloaded from SetUserFTA.exe:
$ua.downloadFile('https://kolbi.cz/SetUserFTA.zip', "$downloadFolder/SetUserFTA.zip")

add-Type -assembly System.IO.Compression.FileSystem
$zip = [IO.Compression.ZipFile]::OpenRead("$downloadFolder/SetUserFTA.zip")
[IO.Compression.ZipFileExtensions]::ExtractToFile($zip.getEntry("SetUserFTA/SetUserFTA.exe"), "$binPath/SetUserFTA.exe")

Enable Clipboard History

The clipboard history should be enabled.

Install newest PowerShell release

Should the newest PowerShell version installed, anyway?
TODO: the following download takes quite a bit of time, and System.Net.WebClient is deprecated anyway. So, try to use downloadFile(), found in the temp-scripts-and-utilities repository.
# $ua.downloadFile('https://github.com/PowerShell/PowerShell/releases/download/v7.0.3/PowerShell-7.0.3-win-x64.zip'                     , "$downloadFolder/PowerShell.zip")
  $ua.downloadFile('https://github.com/PowerShell/PowerShell/releases/download/v7.1.0-preview.6/PowerShell-7.1.0-preview.6-win-x64.zip' , "$downloadFolder/PowerShell.zip")

$newestPsDir = "$binPath/PowerShell7"
if (test-path $newestPsDir) {
   remove-item -recurse $newestPsDir
}

expand-archive $downloadFolder/PowerShell.zip $newestPsDir
addDirToPath $newestPsDir
remove-item "$downloadFolder/PowerShell.zip"

TODO: set-slipboardText set-clipboard

Does the newest PowerShell version come with either set-clipboard or set-clipboardText? Otherwise, it might be added with
install-module -name ClipboardText -force

Install git

Install git.
Download the self extracting executable. There is a portable git, an «ordinary installer» and more. These have their own version number, find newest version number here.
$gitVersion    = '2.29.2'  # Find newest version number under https://github.com/git-for-windows/git
$gitSubVersion =  2

if ([environment]::Is64BitOperatingSystem) {
# $ua.downloadFile("https://github.com/git-for-windows/git/releases/download/v$gitVersion.windows.$gitSubVersion/Git-$gitVersion-64-bit.exe"                          , "$($downloadFolder)Git.exe")
# $ua.downloadFile("https://github.com/git-for-windows/git/releases/download/v$gitVersion.windows.$gitSubVersion/Git-$gitVersion-64-bit.exe"                          , "$($downloadFolder)Git.exe")
  $ua.downloadFile("https://github.com/git-for-windows/git/releases/download/v$gitVersion.windows.$gitSubVersion/PortableGit-$gitVersion.$gitSubVersion-64-bit.7z.exe", "$($downloadFolder)PortableGit.7z.exe")

#
# There would also be a .tar.bz2 file:
#
# $ua.downloadFile("https://github.com/git-for-windows/git/releases/download/v$gitVersion.windows.1/Git-$gitVersion-64-bit.tar.bz2", "$($downloadFolder)Git.exe")

  # LFS Git does not seem necessary enymore
  # $ua.downloadFile("https://github.com/git-lfs/git-lfs/releases/download/v2.7.2/git-lfs-windows-amd64-v2.7.2.zip", "$home\Downloads\git-lfs-windows-amd64.zip")

#
# TODO does the downloaded file really need to have the *amd64* thingy?
#
# $ua.downloadFile("https://github.com/git-lfs/git-lfs/releases/download/v/git-lfs-windows-amd64-v2.7.1.zip", "$home\Downloads\git-lfs-windows-amd64.zip")

} else {
  # echo "64 bit expected"
  $ua.downloadFile("https://github.com/git-for-windows/git/releases/download/v$gitVersion.windows.1/Git-$gitVersion-32-bit.exe", "$($downloadFolder)Git.exe")
}

Install «ordinary» git

Run the downloaded executable (which installs the git executable under C:\Program Files\Git\cmd).
& "$($downloadFolder)Git.exe" /SP- /SUPPRESSMSGBOXES /SILENT /CURRENTUSER
The meaning of the used command line flags is (see https://jrsoftware.org/ishelp/index.php?topic=setupcmdline):
/SP- Disables «This will install.. Do you wish to continue?» prompt at the beginning of Setup
/SUPPRESSMSGBOXES Supress message boxes

Installing portable git

If the portable version of Git was downloaded, execute the *.7z.exe file:
& "${downloadFolder}\PortableGit.7z.exe" -o $binPath\git -y
Add the new directory of the portable git.exe to the PATH environment variable:
addDirToPath "$binPath\git\bin"

Add usr\bin to path

The usr\bin directory under a Git installation has interesting tools such as diff. Thus, …\usr\bin might be added to the PATH environment variable so that these tools are available in a command line environment.

Install git lfs

cd ... data.stadt-zuerich.ch
git lfs install --local

Configure Git

Do long paths have to be enabled on Windows 10 with git?
git config --system core.longpaths true
Possibly, username and password need to be configured, too:
git config --global user.email     "…"
git config --global user.name      "René Nyffenegger"
For some reason that is beyond my intelligence, core.autocrlf seems to be true by default. Therefore, set it to false:
git config --global core.autocrlf   false
Other configurations:
git config --global core.editor     gvim
git config --global diff.tool       gvimdiff
git config --global difftool.prompt false

Create git directories

$null = mkdir $env:github_top_root
$null = mkdir $env:github_top_root\github
$null = mkdir $env:github_top_root\about
$null = mkdir $env:github_top_root\lib
$null = mkdir $env:github_top_root\temp

Install Perl

Install a portable Perl. Strawberry's portable Perl claims that it does not need admin privileges.
Strawberry recommends to put into path without spaces. However, the value of $env:programFiles is C:\Program Files which contains spaces - and I seem to remember that I was able to successfully install Perl below that directory.
# $strawberryPerlDestDir="$env:programFiles\StrawberryPerl"
  $strawberryPerlDestDir="$home\StrawberryPerl"
$null = mkdir $strawberryPerlDestDir

#
# Find perl version under strawberryperl.com/releases.html
#
$perlVersion='5.30.3.1'
if ([environment]::Is64BitOperatingSystem) {
  $ua.downloadFile("http://strawberryperl.com/download/$perlVersion/strawberry-perl-$perlVersion-64bit-PDL.zip" , "$downloadFolder\StrawberryPerl.zip")
} else {
  $ua.downloadFile("http://strawberryperl.com/download/$perlVersion/strawberry-perl-$perlVersion-32bit-PDL.zip" , "$downloadFolder\StrawberryPerl.zip")
}

#
# Unzip zip file with COM object shell.application
#
$shell = new-object -comObject shell.application
$shell.nameSpace($strawberryPerlDestDir).copyHere($shell.nameSpace("$downloadFolder\StrawberryPerl.zip").items())

#
# Other dissapointing trials to unzip zipfile were:
#
#   extrac32 $home\Downloads\StrawberryPerl.zip "$env:programFiles\StrawberryPerl"
#  &rundll32.exe zipfldr.dll,RouteTheCall $home\Downloads\StrawberryPerl.zip

rm $home\Downloads\StrawberryPerl.zip

#
# Set env variables
#
#   portableshell.bat also sets these variables:
#     set TERM=
#     set HOME=%~dp0data
#

$envTarget = 'user' # or 'machine'

addDirToPath $strawberryPerlDestDir\perl\site\bin
addDirToPath $strawberryPerlDestDir\perl\bin
addDirToPath $strawberryPerlDestDir\c\bin
# $envPath = [environment]::getEnvironmentVariable('PATH', $envTarget)
# [environment]::setEnvironmentVariable('PATH'          , "$strawberryPerlDestDir\perl\site\bin;$strawberryPerlDestDir\perl\bin;$strawberryPerlDestDir\c\bin;$envPath", $envTarget) 

[environment]::setEnvironmentVariable('PLPLOT_LIB'    , "$strawberryPerlDestDir\c\share\plplot", $envTarget) 
[environment]::setEnvironmentVariable('PLPLOT_DRV_DIR', "$strawberryPerlDestDir\c\share\plplot", $envTarget) 

Associate .pl extension with Perl executable

TODO: This should now probably be done with SetUserFTA.exe.
Before proceeding with the following snippets, first check if the registry key HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.pl already exists.
$null = new-psDrive -name HKCR -psProvider registry -root HKEY_CLASSES_ROOT

#
# TODO: In Zicke, the .pl key was already existent with a default
# value of 'pl_auto_file' and a subkey, named 'PersistentHandler'
# and default value '{5e941d80-bf96-11cd-b579-08002b30bfeb}'
#
$null = new-item -path HKCR:\.pl
set-item -path HKCR:\.pl -value PerlScript

# Alternatively:
new-item -path HKCU:\Software\Classes\.pl
set-item -path HKCU:\Software\Classes\.pl -value PerlScript


#
# Did not work in Zicke:
#
# new-item -path HKCR:\PerlScript

$null = new-item -path HKCU:\Software\Classes\PerlScript
$null = new-item -path HKCU:\Software\Classes\PerlScript\shell
$null = new-item -path HKCU:\Software\Classes\PerlScript\shell\Open
$null = new-item -path HKCU:\Software\Classes\PerlScript\shell\Open\Command
# $null = set-item -path HKCU:\Software\Classes\PerlScript\shell\Open\Command -value "`"$strawberryPerlDestDir\perl\bin\perl.exe`" `"%1`""
$null = set-item -path HKCU:\Software\Classes\PerlScript\shell\Open\Command -value "`"$strawberryPerlDestDir\perl\bin\perl.exe`" %1 %*"
Add some modules
cpan File::Touch
cpan Net::FTP
cpan Net::FTP::File
cpan Digest::MD5::File
Apparently used for the test case for GraphViz::Graph:
cpan File::MMagic
Test::Files is also used for GraphViz::Graph, but its test suite is defunct. It might be installed, however with -fi (force installation)
cpan -fi Test::Files
# git clone https://github.com/ReneNyffenegger/RN                   ~/github/github
  git clone https://github.com/ReneNyffenegger/RN                   "$($env:github_root)RN"
# git clone https://github.com/ReneNyffenegger/tq84-PerlModules     ~/github/lib
  git clone https://github.com/ReneNyffenegger/tq84-PerlModules     "$($env:github_top_root)lib/tq84-PerlModules"
TODO: at least the RN module name and installation location need to be changed.

Clone some git repositories

localgit

# git clone e:\git $env:userprofile\localgit
git clone e:\git $env:git_work_dir

Add new script directory to path environment variable

addDirToPath "$($env:git_work_dir)scripts"

github script repository

# git clone https://github.com/ReneNyffenegger/scripts-and-utilities $env:userprofile/github/lib/scripts
git clone https://github.com/ReneNyffenegger/scripts-and-utilities "$($env:github_top_root)lib\scripts"

Add new script directory to path environment variable

addDirToPath "$($env:github_top_root)lib\scripts"

Configure cmd.exe

Check if registry key HKEY_CURRENT_USER\Software\Microsoft\Command Processor exists and what the values of CompletionChar, PathCompletionChar and EnableExtensions are.
If the key does not exist, create it with
new-item -path 'hkcu:\Software\Microsoft\Command Processor'
Make sure that HKEY_CURRENT_USER\Console\%SystemRoot%_system32_cmd.exe exists, otherwise create it with
new-item -path 'hkcu:\Console\%SystemRoot%_system32_cmd.exe'
Set the window and buffer size of cmd.exe, font size and allow copying text (quick edit).

Environment variable PROMPT

Windows 10 comes with ANSI escape sequences, thus, the prompt can be colored:
[environment]::setEnvironmentVariable('PROMPT', '$e[38;5;6m$t$s$e[38;5;10m$p$_$e[38;5;9m$+$g$s$e[38;5;15m', 'user')
Set the %PROMPT% environment variable (without ANSI colors):
[environment]::setEnvironmentVariable("PROMPT", '$t$s$p$_$+$g$s', 'user') 

Environment variable DIRCMD

Set the DIRCMD variable to specify the default behaviour of dir:
[environment]::setEnvironmentVariable('DIRCMD', '/ogn /a', 'user')

autorun.bat

Assign a batch file to be run when cmd.exe is started (Value of autorun under registry key HKEY_CURRENT_USER\Software\Microsoft\Command Processor).
PS C:\> # new-itemProperty -path 'hkcu:\Software\Microsoft\Command Processor' -name autorun -value "$($env:userprofile)\github\lib\scripts\autorun.bat" -force
PS C:\> $null = new-itemProperty -path 'hkcu:\Software\Microsoft\Command Processor' -name autorun -value "$($env:github_top_root)\lib\scripts\autorun.bat" -force
The autorun.bat was installed previously in Clone github repositories.

Transparent cmd.exe

With Windows 10, cmd.exe can be made transparent - not sure, though, if I really want that!

gvim / vim

Compiling

Strawberry Perl comes with a C compiler which can be used to compile vim.
Make sure that the setting of the variable github_top_root has already taken effect.
cd $env:github_top_root
git clone https://github.com/vim/vim
# cd $env:github_top_root\vim\src
cd vim\src
Edit feature.h to match preferences.
If Perl is installed under C:\Program Files (which contains spaces), the installation directory's short name needs to be determined:
$fso = new-object -comObject scripting.fileSystemObject
$perlShortPath = $fso.getFolder("$env:programFiles\StrawberryPerl\perl").shortPath
The ARCH=native option is passed to gcc via the -march option. Additionally, it prevents the make file from trying to invoke sed which is not yet installed.
Define XPM=no to prevent fatal error: xpm.h: no such file or directory.
The option TERMINAL=yes builds vim with terminal support (winpty, :help terminal)
Using short path:
gmake -f Make_ming.mak PERL=$perlShortPath DYNAMIC_PERL=yes PERL_VER=528 ARCH=native XPM=no
Alternative build-execution using the variable $strawberryPerlDestDir:
gmake -f Make_ming.mak PERL=$($strawberryPerlDestDir -replace '\\', '/')/perl DYNAMIC_PERL=yes PERL_VER=530 ARCH=x86-64 TERMINAL=yes
cp gvim.exe     $home\bin
cp vimrun.exe   $home\bin
cp xxd\xxd.exe  $home\bin
Set the VIMRUNTIME environment variable
[environment]::setEnvironmentVariable('VIMRUNTIME', "$($env:github_top_root)vim\runtime", 'user') 
Clone .vim
git clone https://github.com/ReneNyffenegger/.vim $home\vimfiles

Installing from the self extracting exe

Alternatively, gvim might be installed with an installer, downloadable from https://ftp.nluug.nl/pub/vim/pc/gvim81.exe.
The default installation folder is C:\Program Files (x86)\Vim. Without administrator rights, another installation folder is needed, for example %homedrive%%homepath%\Vim.
Apparently, the installer does not set adjust the PATH variable. So, it needs to be set manually:
PS C:\> $userPath = [environment]::getEnvironmentVariable("PATH", "user"    )
PS C:\> [environment]::setEnvironmentVariable('PATH', "$($env:HOMEDRIVE)$($env:HOMEPATH)Vim\vim81;$userPath", "user") 
TODO:
  • The Edit-with-Vim context menu entry
  • The _vimrc file which is installed if it does not exist
  • The plugin directory in HOME or VIM

create .netrc

Create a .netrc file in %USERPROFILE%.

Install portable apps

Portable apps to install:

Install RemoveDrive

$ua.downloadFile('https://www.uwe-sieber.de/files/removedrive.zip', "$downloadFolder\removedrive.zip");
#
#  Extract only exe from zip file. Note: there is also a 32-bit version
#
$removedrive_exe=$shell.namespace("${downloadFolder}removedrive.zip").items().item('x64\RemoveDrive.exe');
$shell.nameSpace($binPath).copyHere($removedrive_exe);
See also ejusb.bat

AutoHotKey

A user agent needs to be specified in order to prevent The remote server returned an error: (403) forbiddden.
$ua = new-object system.net.webClient
$ua.headers.add('User-Agent', 'Mozilla/5.0 (the-OS)')
$ua.downloadFile("https://www.autohotkey.com/download/1.1/AutoHotkey_1.1.30.03.zip"        , "$home\Downloads\AutoHotkey_1.1.zip"     )
$ua.downloadFile("https://www.autohotkey.com/download/2.0/AutoHotkey_2.0-a103-56441b52.zip", "$home\Downloads\AutoHotkey_v2.0-x64.zip")

$shell = new-object -comObject shell.application

#
# TODO: V 1.1 also contains a compiler and some *.ahk files.
#
$shell.nameSpace("$home\bin").copyHere("$home\Downloads\AutoHotKey_1.1.zip\AutoHotkeyU64.exe")
$shell.nameSpace("$home\bin").copyHere("$home\Downloads\AutoHotKey_1.1.zip\WindowSpy.ahk"    ) # TODO: should the spy really be copied here?
mv $home\bin\AutoHotkeyU64.exe $home\bin\ahk.exe

$shell.nameSpace("$home\bin").copyHere("$home\Downloads\AutoHotkey_v2.0-x64.zip\AutoHotkeyU64.exe")
mv -force $home\bin\AutoHotkeyU64.exe   $home\bin\ahk2.exe

rm $home\Downloads\AutoHotkey_1.1.zip
rm $home\Downloads\AutoHotkey_v2.0-x64.zip
Also: add an filetype association for the .ahk2 suffix:
# new-psDrive -name HKCR -psProvider registry -root HKEY_CLASSES_ROOT
# $classRoot = 'HKCR:\'
$classRoot = 'HKCU:\Software\Classes'
$ext_ahk2 = new-item -path $classRoot -name .ahk2
#
# Set default value
#
$ext_ahk2.setValue('', 'AHK2Script')

$ahk2script         = new-item -path $classRoot -name AHK2Script
$ahk2script_command = $ahk2script.createSubKey('Shell\Open\Command')
$ahk2script_command.setValue('', "$home" + '\bin\ahk2.exe "%1" %*')

R and RStudio

Find link for RStudio here.
[net.servicePointManager]::securityProtocol = [net.securityProtocolType]::Tls12
$ua = new-object system.net.webClient
# $ua.headers.add('User-Agent', 'Mozilla/5.0 (the-OS)')
$ua.downloadFile("https://cran.rstudio.com/bin/windows/base/R-3.6.0-win.exe"         , "$downloadFolder\R.exe"       )
$ua.downloadFile("https://download1.rstudio.org/desktop/windows/RStudio-1.2.1335.exe", "$downloadFolder\RStudio.exe" )

& $home\Downloads\R.exe
& $home\Downloads\RStudio.exe
Probably, it's easier to install R and RStudio with chocolatey

Graphviz

Install Graphviz: a zip file can be found at https://graphviz.gitlab.io/_pages/Download/Download_windows.html.
PS C:\> $ua.downloadFile('https://graphviz.gitlab.io/_pages/Download/windows/graphviz-2.38.zip', "$downloadFolder\graphviz.zip")
PS C:\> tar -C $env:temp -xf $downloadFolder\graphviz.zip release/bin/*
PS C:\> move-item $env:temp\release\bin\* $binPath
PS C:\> remove-item -recurse $env:temp\release

After installing Office

Grant access to VBA Object Model (for example under the registry key HKCU\Software\Microsoft\Office\x.y\Excel\Security).
Add the developer tab to the ribbon.
Change options: Excel and Word.
Disable animations.
Stop the annoying desktop alert when new eMails arrive.

(After) installing Oracle

Clone the scripts that go into the $env:SQLPATH location.
PS C:\> $null = new-item -type directory $env:github_top_root/Oracle
PS C:\> git clone https://github.com/ReneNyffenegger/Oracle-SQLPATH "$($env:github_top_root)Oracle\SQLPATH"
PS C:\> [environment]::setEnvironmentVariable('SQLPATH', "$($env:github_top_root)Oracle\SQLPATH", 'user') 
PS C:\> [environment]::setEnvironmentVariable('ORACLE_HOME', 'C:\Oracle\19', 'user') 
PS C:\> [environment]::setEnvironmentVariable('ORACLE_SID' , 'ORA19'       , 'user') 

Add User accounts

Add another user account:
C:\> net user john johnsPassword /add
When logged in as that user, change the desktop background image:
PS:\> set-itemProperty -path 'HKEY_CURRENT_USER\Control Panel\Desktop' -name wallpaper -value $env:userProfile\Pictures\IMG_2104.JPG
PS:\> rundll32.exe user32.dll,UpdatePerUserSystemParameters

Misc

Install
Use powercfg.exe to change power settings so that computer does not go to sleep anymore.
Don't reboot while someone is logged on
Enable the system global flag maintain objects list so that openfiles.exe is able to report blocking files. Note, this requires a reboot to take effect:
openfiles /local on

Download and install Image Magick

Image Magick comes in handy from time to time.
The download links can be found here.
# 64 Bit:
  $ua.downloadFile('https://imagemagick.org/download/binaries/ImageMagick-7.0.10-2-portable-Q16-x64.zip', "$downloadFolder\ImageMagick-portable.zip")
# 32 Bit
# $ua.downloadFile('https://imagemagick.org/download/binaries/ImageMagick-7.0.10-2-portable-Q16-x86.zip', "$downloadFolder\ImageMagick-portable.zip")
tar -xf $downloadFolder\ImageMagick-portable.zip  -C $binPath convert.exe identify.exe mogrify.exe ffmpeg.exe
Alternatively, the .zip file can also be extracted with PowerShell
expand-archive $downloadFolder\ImageMagick-portable.zip  $binPath\ImageMagick
addDirToPath $binPath\ImageMagick

Download and install openssl

TODO: Strawberry Perl already has an openssl executable. It is located under c/bin under Strawberry's root installation directory.
TODO: $binPath might already have a libeay32.dll and a ssleay32.dll.
TODO: Apparently gnupg should be used instead of openssl, at least when not used as a library but on the command line.
$ua.downloadFile('https://indy.fulgan.com/SSL/openssl-1.0.2t-x64_86-win64.zip', "$downloadFolder\openssl.zip")
tar xf $downloadFolder\openssl.zip -C $binPath

Utilities that help configure Windows

boxstarter makes «repeatable and reboot resilient» windows enviornment easy using Chocolatey packages.

TODO

Set _NT_SYMBOL_PATH:
[environment]::setEnvironmentVariable('_NT_SYMBOL_PATH', "srv*$env:ProgramData\Dbg*https://msdl.microsoft.com/download/symbols", 'user')
Use the startLayout cmdLet noun to configure the Start menu.
https://gist.github.com/godofice/f2c8bf79473068b7f120
Should WinCDEmu be used? It allows to mount .iso files with a right click in explorer.exe.
Values under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\Installed Components
How do I enable long paths?
Enable auto logon?
Disable the webcam
What is a users logon id (whoami /logonid)?
Change wallpaper
Remove News and Interests from the Taskbar: hide-NewsAndInterest
Which processes are seen to run after installation?
Which services are installed?
Which programs do autorun?
msconfig.exe, Startup tab.
What about HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Winlogon, value of ParseAutoexec?
Where does Sysinternals's Process Monitor store its settings?
Changing the start page of Internet Explorer (respectively that of Edge).
Remove unnecessary directories under %UserProfile%.
What is auto-run? Why is OneDrive.exe started?
Enable long file paths
Can Cortana be turned off/disabled?
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects, HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\DWM and SystemPropertiesAdvanced.exe
Enable entering Unicode characters.
Does %SystemRoot%\Installer need to be cleaned up with PatchCleaner?
Check Start -> Settings -> Privacy -> Diagnostics & Feedback
Does the DefaultSecureProtocols value have to be changed under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp?
Can I use Boxstarter to post-install applications and environments on Windows?

Exclude certain paths from being checked by Anti virus

set-mpPreference -exclusionPath C:\Users\Rene\renenyffenegger.ch\web\notes
Possibly, add-mpPreference is preferred over set-mpPreference.

Sounds

Should Beep and ExtendedSound under the registry key HKEY_CURRENT_USER\Control Panel\Sound be set to no?

JDK

$systemPath = [environment]::getEnvironmentVariable("PATH", "machine")

# $jdkVersion = '12'
$jdkVersion = 'jdk1.8.0_211'

[environment]::setEnvironmentVariable('PATH'     , "c:\Program Files\Java\$jdkVersion\bin;$systemPath", 'machine')
[environment]::setEnvironmentVariable('JAVA_HOME', "c:\Program Files\Java\$jdkVersion"                , 'machine')

Backup, restore and recovery

Create a System image
File History Control Panel -> System and Security -> File History
See also

Install NuGet package provider

install-packageProvider -name NuGet                           -force
install-packageProvider -name NuGet -minimumVersion 2.8.5.201 -force

nuget.exe

PS C:\users\Rene> downloadFile 'https://dist.nuget.org/win-x86-commandline/latest/nuget.exe' "$binPath\nuget.exe"

Install PowerShell module psWindowsUpdate

Install the PowerShell module psWindowsUpdate so that Windows updates can be performed from the command line.
Apparently, after installing the NuGet package provider, a new session needs to be started for the following operation to succeed:
install-Module psWindowsUpdate -force

Links

This github repository tries to show that it is possible to configure Windows without using third-party programs.
Martin Willey: Setting up a new Machine

Index