Skip to content

Instantly share code, notes, and snippets.

@AndriyShepitsen
Forked from zloeber/bootstrapwindows10.ps1
Last active February 28, 2021 01:38
Show Gist options
  • Save AndriyShepitsen/b2fca661888c9e92dad7324bac5e0dd6 to your computer and use it in GitHub Desktop.
Save AndriyShepitsen/b2fca661888c9e92dad7324bac5e0dd6 to your computer and use it in GitHub Desktop.
Boxstarter Windows 10 Configuration
<#
The command to run, built from the raw link of this gist
Win+R
iexplore http://boxstarter.org/package/url?<RAW GIST LINK>
OR (if you don't like the way the web launcher force re-installs everything)
Create another script like the following to install and run the gist:
. { iwr -useb http://boxstarter.org/bootstrapper.ps1 } | iex; get-boxstarter -Force
install-boxstarterpackage -PackgeName <RAW GIST URL>
NOTES:
- This may need to be run a few times to get 100% to a finished state (though it should reboot and pick up where it left off)
- If you use windows hello or fingerprint scanning for authentication then just press enter 3x when
prompted for a password (and know that passwordless relogin will not work after a reboot)
- You will almost certainly want to modify the configuration and every other aspect of this script
to meet your own needs.
#>
# Boxstarter options
$Boxstarter.RebootOk=$true # Allow reboots?
$Boxstarter.NoPassword=$true # Is this a machine with no login password?
$Boxstarter.AutoLogin=$true # Save my password securely and auto-login after a reboot
# All of the configuration tasks that will be run.
# Downloads of non-chocolatey installed apps will go here (within system root)
$UtilDownloadPath = join-path $env:systemdrive 'Utilities\Downloads'
# Hahicorp manually installed apps go here and this gets added to your path
$UtilBinPath = join-path $env:systemdrive 'Utilities\bin'
# Releases based github packages to download and install. I include Keeweb and the Hack font I love so dearly
$GithubReleasesPackages = @{
'keeweb/keeweb' = "keeweb*win.x64.exe"
'source-foundry/Hack-windows-installer' = "HackWindowsInstaller.exe"
}
# PowerShell Modules to install
$ModulesToBeInstalled = @(
'Configuration',
'CredentialManager',
'dbatools',
'EZOut',
'HistoryPx',
'InvokeBuild',
'PackageManagement',
'Pansies',
'platyPS',
'posh-git',
'PowerLine',
'PowerShellGet',
'powershell-yaml',
'psake',
'PSCodeHealth',
'PSDecode',
'PSDepend',
'PSGit',
'PSGraph',
'psmsgraph',
'PSScriptAnalyzer',
'SharePointPnPPowerShellOnline',
'SnippetPx',
'WinSCP',
'OhMyPsh'
)
# Chocolatey packages to install
$ChocoInstalls = @(
'7zip',
'7zip.commandline',
'cmder',
'Opera'
'Teamviewer'
'Firefox',
'foxitreader',
'GoogleChrome',
'sysinternals'
'hub',
'keypirinha',
'nano',
'nmap',
'notepadplusplus',
'paint.net',
'PDFCreator',
'procexp',
'sharex',
'superputty',
'terminals',
'toolsroot',
'VirtualCloneDrive',
'vlc',
'win32diskimager',
'windirstat',
'winscp',
'wireshark',
'yumi',
'cutepdf'
'zoom'
)
# Chocolatey places a bunch of crap on the desktop after installing or updating software. This flag allows
# you to clean that up (Note: this will move *.lnk files from the Public user profile desktop and your own
# desktop to a new directory called 'shortcuts' on your desktop. This may or may not be what you want..)
$ClearDesktopShortcuts = $True
# Use the $MyPowerShellProfile to create a new powershell profile if one doesn't already exist
$CreatePowershellProfile = $TRUE
$MyPowerShellProfile = @'
## Detect if we are running powershell without a console.
$_ISCONSOLE = $TRUE
try {
[System.Console]::Clear()
}
catch {
$_ISCONSOLE = $FALSE
}
# Everything in this block is only relevant in a console. This keeps nonconsole based powershell sessions clean.
if ($_ISCONSOLE) {
## Check SHIFT state ASAP at startup so we can use that to control verbosity :)
try {
Add-Type -Assembly PresentationCore, WindowsBase
if ([System.Windows.Input.Keyboard]::IsKeyDown([System.Windows.Input.Key]::LeftShift) -or [System.Windows.Input.Keyboard]::IsKeyDown([System.Windows.Input.Key]::RightShift)) {
$VerbosePreference = "Continue"
}
}
catch {
# Maybe this is a non-windows host?
}
## Set the profile directory variable for possible use later
Set-Variable ProfileDir (Split-Path $MyInvocation.MyCommand.Path -Parent) -Scope Global -Option AllScope, Constant -ErrorAction SilentlyContinue
# Start OhMyPsh only if we are in a console
if ($Host.Name -eq 'ConsoleHost') {
if (Get-Module OhMyPsh -ListAvailable) {
Import-Module OhMyPsh
}
}
}
# Relax the code signing restriction so we can actually get work done
Import-module Microsoft.PowerShell.Security
Set-ExecutionPolicy RemoteSigned Process
'@
# Install boxstarter (which installs chocolatey as well).
#Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('http://boxstarter.org/bootstrapper.ps1')); get-boxstarter -Force
# Basic setup (Boxstarter stuff)
#Update-ExecutionPolicy RemoteSigned
Enable-MicrosoftUpdate
#Set-CornerNavigationOptions -DisableUpperRightCornerShowCharms -DisableUpperLeftCornerSwitchApps -EnableUsePowerShellOnWinX
function Read-Choice {
Param(
[Parameter(Position = 0)]
[System.String]$Message,
[Parameter(Position = 1)]
[ValidateNotNullOrEmpty()]
[System.String[]]$Choices = @('&Yes', '&No', 'Yes to &All', 'No &to All'),
[Parameter(Position = 2)]
[System.Int32]$DefaultChoice = 0,
[Parameter(Position = 3)]
[System.String]$Title = [string]::Empty
)
[System.Management.Automation.Host.ChoiceDescription[]]$Poss = $Choices | ForEach-Object {
New-Object System.Management.Automation.Host.ChoiceDescription "$($_)", "Sets $_ as an answer."
}
$Host.UI.PromptForChoice( $Title, $Message, $Poss, $DefaultChoice )
}
Function Get-SpecialPaths {
$SpecialFolders = @{}
$names = [Environment+SpecialFolder]::GetNames([Environment+SpecialFolder])
foreach($name in $names) {
$SpecialFolders[$name] = [Environment]::GetFolderPath($name)
}
$SpecialFolders
}
Function Get-EnvironmentVariableNames {
param (
[string]$Scope
)
([Environment]::GetEnvironmentVariables($Scope).GetEnumerator()).Name
}
Function Get-EnvironmentVariable {
param (
[string]$Name,
[string]$Scope
)
[Environment]::GetEnvironmentVariable($Name, $Scope)
}
Function Update-SessionEnvironment {
<#
Ripped directly from the chocolatey project, used here just for initial setup
#>
$refreshEnv = $false
$invocation = $MyInvocation
if ($invocation.InvocationName -eq 'refreshenv') {
$refreshEnv = $true
}
if ($refreshEnv) {
Write-Output "Refreshing environment variables from the registry for powershell.exe. Please wait..."
}
else {
Write-Verbose "Refreshing environment variables from the registry."
}
$userName = $env:USERNAME
$architecture = $env:PROCESSOR_ARCHITECTURE
$psModulePath = $env:PSModulePath
#ordering is important here, $user comes after so we can override $machine
'Process', 'Machine', 'User' |
% {
$scope = $_
Get-EnvironmentVariableNames -Scope $scope |
% {
Set-Item "Env:$($_)" -Value (Get-EnvironmentVariable -Scope $scope -Name $_)
}
}
#Path gets special treatment b/c it munges the two together
$paths = 'Machine', 'User' |
% {
(Get-EnvironmentVariable -Name 'PATH' -Scope $_) -split ';'
} |
Select -Unique
$Env:PATH = $paths -join ';'
# PSModulePath is almost always updated by process, so we want to preserve it.
$env:PSModulePath = $psModulePath
# reset user and architecture
if ($userName) { $env:USERNAME = $userName; }
if ($architecture) { $env:PROCESSOR_ARCHITECTURE = $architecture; }
if ($refreshEnv) {
Write-Output "Finished"
}
}
Function Add-EnvPath {
# Adds a path to the $ENV:Path list for a user or system if it does not already exist (in both the system and user Path variables)
param (
[string]$Location,
[string]$NewPath
)
$AllPaths = $Env:Path -split ';'
if ($AllPaths -notcontains $NewPath) {
Write-Output "Adding Utilties bin directory path to the environmental path list: $UtilBinPath"
$NewPaths = (@(([Environment]::GetEnvironmentVariables($Location).GetEnumerator() | Where {$_.Name -eq 'Path'}).Value -split ';') + $UtilBinPath | Select-Object -Unique) -join ';'
[Environment]::SetEnvironmentVariable("PATH", $NewPaths, $Location)
}
}
function Start-Proc {
param([string]$Exe = $(Throw "An executable must be specified"),
[string]$Arguments,
[switch]$Hidden,
[switch]$waitforexit)
$startinfo = New-Object System.Diagnostics.ProcessStartInfo
$startinfo.FileName = $Exe
$startinfo.Arguments = $Arguments
if ($Hidden) {
$startinfo.WindowStyle = 'Hidden'
$startinfo.CreateNoWindow = $True
}
$process = [System.Diagnostics.Process]::Start($startinfo)
if ($waitforexit) { $process.WaitForExit() }
}
function Get-HashiCorpLatestVersion {
<#
function to find the most recent version in the json manifest
Note: We ignore anything not in strict x.x.x version format (betas and such)
#>
param(
$manifest,
$software
)
(($manifest.$software.versions | get-member -MemberType 'NoteProperty').Name | Where {$_ -match "^\d+\.\d+\.\d+$"} | ForEach-Object {[version]$_} | Sort-Object -Descending | Select-Object -First 1).ToString()
}
function Get-AllHashiCorpPackageLatestVersion {
<#
.SYNOPSIS
Retreives the most recent version of Hashicorp software packages from a json manifest
.DESCRIPTION
Retreives the most recent version of Hashicorp software packages from a json manifest
.PARAMETER manifest
JSON manifest data to search.
.EXAMPLE
Get-AllHashiCorpPackageLatestVersion
.NOTES
Author: Zachary Loeber
#>
param(
$manifest
)
$OutHash = @{}
$manifest | Get-Member -MemberType 'NoteProperty' | Foreach {
$OutHash.($_.Name) = Get-HashiCorpLatestVersion $manifest $_.Name
}
$OutHash
}
function Get-ChocoPackages {
if (get-command clist -ErrorAction:SilentlyContinue) {
clist -lo -r -all | Foreach {
$Name,$Version = $_ -split '\|'
New-Object -TypeName psobject -Property @{
'Name' = $Name
'Version' = $Version
}
}
}
}
# Add a path for windows defender to bypass
function Add-DefenderBypassPath {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true, ValueFromPipeline = $true)]
[string[]]$Path
)
begin {
$Paths = @()
}
process {
$Paths += $Path
}
end {
$Paths | Foreach-Object {
if (-not [string]::isnullorempty($_)) {
Add-MpPreference -ExclusionPath $_ -Force
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment