Skip to content

Instantly share code, notes, and snippets.

@techthoughts2
Last active August 28, 2024 00:46
Show Gist options
  • Save techthoughts2/3b3f44ddbac0cc8f8331b7d97c2162f8 to your computer and use it in GitHub Desktop.
Save techthoughts2/3b3f44ddbac0cc8f8331b7d97c2162f8 to your computer and use it in GitHub Desktop.
This PowerShell script will setup a fresh workstation with everything needed to sucessfully work and be a DevOps Master day-to-day.
#region installs
# core tech choco installs
$script:chocoCoreTech = @(
# 'vscode' # visual studio code
# 'python' # python
# '7zip' # file archiver with good compression ratio
# 'git' # git for windows
# 'firefox' # firefox browser
)
# core tech winget installs
$script:wingetCoreTech = @(
'Git.Git' # git for windows
'Microsoft.VisualStudioCode' # visual studio code
'Python.Python.3' #python
'7zip.7zip' # file archiver with good compression ratio
'Mozilla.Firefox' # firefox browser
'JanDeDobbeleer.OhMyPosh' # oh my posh
'Microsoft.PowerShell' # powershell
)
# basic choco installs
$script:chocoSoftwareInstalls = @(
# 'ytmdesktop' #https://github.com/ytmdesktop/ytmdesktop/issues/563
# 'spotify' # spotify
# 'cacher' # code snippet organizer
# 'winscp' # Open source free SFTP client, SCP client, FTPS client and FTP client
# 'telegram' # Cloud-based synchronized messaging app with a focus on speed and security
# 'grepwin' # powerful and fast search tool using regular expressions.
# 'notepadplusplus' # source code editor and Notepad replacement
# 'googlechrome' # chrome browser
# 'foxitreader' # pdf client
'paint.net' # photo editor
)
# basic winget installs
$script:wingetSoftwareInstalls = @(
'Spotify.Spotify' # spotify
'PenguinLabs.Cacher' # code snippet organizer
'WinSCP.WinSCP' # Open source free SFTP client, SCP client, FTPS client and FTP client
'Telegram.TelegramDesktop' # Cloud-based synchronized messaging app with a focus on speed and security
'StefansTools.grepWin' # powerful and fast search tool using regular expressions.
'Notepad++.Notepad++' # source code editor and Notepad replacement
# 'Google.Chrome' # chrome browser
# 'Foxit.FoxitReader' # pdf client
'JGraph.Draw' # draw.io
'WinDirStat.WinDirStat' # disk usage analyzer
'NickeManarin.ScreenToGif' # screen recorder to gif
'DominikReichl.KeePass' #KeePass
)
# choco azure installs
$script:chocoInstallsAzure = @(
# 'azure-cli' # cli for azure
# 'AzureStorageExplorer' # the azure storage explorer
# 'azure-functions-core-tools-3' # core tool set for local dev of azure functions
'azcopy10' # azure copy tool
# 'bicep' # bicep cli
)
# winget azure installs
$script:wingetInstallsAzure = @(
'Microsoft.AzureCLI' # cli for azure
'Microsoft.AzureStorageExplorer' # the azure storage explorer
'Microsoft.AzureFunctionsCoreTools' # core tool set for local dev of azure functions
'Microsoft.AzureStorageEmulator'
'Microsoft.Bicep' # bicep cli
)
# choco aws installs
$script:chocoInstallsAWS = @(
'aws-vault' # A tool to securely store and access AWS credentials in a development environment
# 'awscli' # aws cli
)
# winget aws installs
$script:wingetInstallsAWS = @(
'Amazon.AWSCLI' # aws cli
'Amazon.SAM-CLI' # aws sam cli
'Amazon.SessionManagerPlugin' # aws session manager plugin
)
# winget aws cdk typescript installs
$script:wingetAWSCDKTypeScript = @(
'Amazon.AWSCLI' # aws cli
'OpenJS.NodeJS' # nodejs
)
# a list of useful Azure PowerShell modules
$script:azureModules = @(
'Az' # standard Azure modules
'AzureDevOps' # interact with the Azure DevOps REST API.
'AzurePipelinesPS' # makes interfacing with Azure Pipelines a bit easier.
'CosmosDB' # provides cmdlets for working with Azure Cosmos DB.
'PSArm' # experimental DSL for ARM templates (based on bicep)
'Bicep' # enable the features provided by the Bicep CLI in PowerShell.
)
# a list of useful AWS PowerShell modules
$script:awsModules = @(
'AWS.Tools.Common'
'AWS.Tools.CloudWatch'
'AWS.Tools.CostExplorer'
'AWS.Tools.S3'
'AWS.Tools.SecretsManager'
'AWS.Tools.SecurityToken'
'AWS.Tools.SQS'
)
# a list of useful Core PowerShell modules
$script:modules = @(
@{
ModuleName = 'Catesta'
Version = 'Latest'
}
@{
ModuleName = 'Convert'
Version = 'Latest'
}
@{
ModuleName = 'DnsClient-PS'
Version = 'Latest'
}
@{
ModuleName = 'InvokeBuild'
Version = 'Latest'
}
@{
ModuleName = 'Pester'
Version = 'Latest'
}
@{
ModuleName = 'platyPS'
Version = '0.12.0'
}
@{
ModuleName = 'posh-git'
Version = 'Latest'
}
@{
ModuleName = 'PoshGram'
Version = 'Latest'
}
@{
ModuleName = 'PSReadline'
Version = 'Latest'
}
@{
ModuleName = 'PSScriptAnalyzer'
Version = 'Latest'
}
@{
ModuleName = 'PSWordCloud'
Version = 'Latest'
}
@{
ModuleName = 'Terminal-Icons'
Version = 'Latest'
}
)
# python VSCode extensions
$script:vscodeExtensionsPython = @(
'almenon.arepl' #AREPL automatically evaluates python code in real-time as you type.
'formulahendry.code-runner' #Run code snippet or code file for multiple languages:
'ms-python.python' #python
'ms-python.vscode-pylance' #Fast, feature-rich language support for Python
'ms-toolsai.jupyter' #basic notebook support for language kernels
'njpwerner.autodocstring' #quickly generate docstrings for python functions.
)
# aws VSCode extensions
$script:vscodeExtensionsAWS = @(
'amazonwebservices.aws-toolkit-vscode' #AWS Toolkit is an extension for Visual Studio Code that enables you to interact with Amazon Web Services (AWS).
'aws-scripting-guy.cform' #CloudFormation support
'DanielThielking.aws-cloudformation-yaml' #This extension adds some snippets to YAML based files for AWS CloudFormation.
'kddejong.vscode-cfn-lint' #VS Code CloudFormation Linter uses cfn-lint to lint your CloudFormation templates.
)
# aws cdktf VSCode extensions
$script:vscodeExtensionsAWSCDK = @(
'dbaeumer.vscode-eslint' #Integrates ESLint JavaScript into VS Code.
)
# azure VSCode extensions
$script:vscodeExtensionsAzure = @(
'damienaicheh.azure-devops-snippets' #Azure DevOps snippets
'ms-dotnettools.vscode-dotnet-runtime' #.NET Install Tool for Extension Authors - dependency
'ms-azure-devops.azure-pipelines' #Syntax highlighting, IntelliSense, and more for Azure Pipelines YAML
'ms-azuretools.vscode-azureresourcegroups' #View and manage Azure resources directly from VS Code.
'ms-azuretools.vscode-azurefunctions' #Use the Azure Functions extension to quickly create, debug, manage, and deploy serverless apps directly from VS Code.
'msazurermtools.azurerm-vscode-tools' #The Azure Resource Manager (ARM) Tools for Visual Studio Code
'ms-azuretools.vscode-bicep' #Bicep language support
'ms-vscode.azure-account' #The Azure Account extension provides a single Azure sign-in
'ms-vscode.azurecli' #Scrapbooks for developing and running commands with the Azure CLI.
)
# core VSCode extensions
$script:vscodeExtensions = @(
'aaron-bond.better-comments' #The Better Comments extension will help you create more human-friendly comments in your code.
'alexey-strakh.stackoverflow-search' #search stackoverflow direct from vscode
'DavidAnson.vscode-markdownlint' #Markdown/CommonMark linting and style checking
'DotJoshJohnson.xml' #xml tools
'eamodio.gitlens' #GitLens supercharges the Git capabilities
'emilast.LogFileHighlighter' #Adds color highlighting to log files
# 'GitHub.copilot' #AI pair programmer from GitHub
'hediet.vscode-drawio' #This unofficial extension integrates Draw.io
'mechatroner.rainbow-csv' #Highlight columns in comma (.csv), tab (.tsv), semicolon and pipe
# 'ms-dotnettools.csharp' #Welcome to the C# extension for Visual Studio Code!
'ms-vscode.powershell' #PowerShell!
'nobuhito.printcode' #adds print to VSCode
'oderwat.indent-rainbow' #make indentation more readable
'PKief.material-icon-theme' #material icon theme for icons
'redhat.vscode-yaml' #Provides comprehensive YAML Language support - dependency
'ritwickdey.LiveServer' #go live
'ryanluker.vscode-coverage-gutters' #codecoverage indicator
'ryu1kn.partial-diff' #You can compare (diff) text selections within a file, across different files, or to the clipboard
'shd101wyy.markdown-preview-enhanced' #Markdown Preview Enhanced
'SirTori.indenticator' #Visually highlights the current indent depth.
'streetsidesoftware.code-spell-checker' #A basic spell checker that works well with camelCase code.
'tuxtina.json2yaml' #Uses js-yaml to do the actual conversion json to yaml and vice-versa.
'Tyriar.shell-launcher' #Easily launch multiple shell configurations in the terminal.
'usernamehw.errorlens' #ErrorLens turbo-charges language diagnostic features by making diagnostics stand out more prominently
'vangware.dark-plus-material' #theme
'vincentkos.snippet-creator' #helps to automate snippet creation
'wmontalvo.vsc-jsonsnippets' #Makes writing key-value code (like JSON) fluent, with a simple set of snippets
'yzhang.markdown-all-in-one' #All you need for Markdown
)
#endregion
#region paths
$script:tempPath = -join ($env:TEMP, '\ws_setup')
$script:vscodeSettingsPath = -join ($env:APPDATA, '\Code\User')
$script:vscodeSnippetsPath = -join ($env:APPDATA, '\Code\User\snippets')
$script:windowsTerminalSettingsPath = -join ($env:LOCALAPPDATA, '\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState')
$script:windowsTerminalBackgroundPath = -join ($env:LOCALAPPDATA, '\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\RoamingState')
# $script:profilePath = -join ($env:USERPROFILE, '\Documents\PowerShell')
# $script:profilePath = $profile.CurrentUserAllHosts
$script:ohmyposhSettings = $env:USERPROFILE
#endregion
#region content locations
$gistUrl = "https://api.github.com/gists/a208d2bd924691bae7ec7904cab0bd8e"
$script:psProfile = 'https://api.github.com/gists/2b4d8e590a7fa41f32a76013df664020'
$script:vsCodeSettingsJSON = 'https://api.github.com/gists/d0997337224510743e2072dc5c343363' #settings.json
$script:vsCodePythonSnippetsJSON = 'https://api.github.com/gists/042b2b47e7a94c1a5a2bc79439a4fb81' #vscode_python_snippets.json
$script:vsCodePowerShellSnippetsJSON = 'https://api.github.com/gists/9ec91ab0ca26f96cf7ca4842053fa8fb' #vscode_ps_snippets.json
$script:windowsTerminalSettingsJSON = 'https://api.github.com/gists/df416a8df55c6c4009c9dcd337d4c8cf' #settings.json
$script:ohmyposhJSON = 'https://api.github.com/gists/da99b8255a8ca720430d188f649a9bd7' #.jake.omp.json
$script:setupFiles = 'https://tt-ws.s3-us-west-2.amazonaws.com/ws.zip' #zip containing background images and fonts
#endregion
#region supporting functions
<#
.SYNOPSIS
Evaluates if chocolatey is installed
#>
function Test-Choco {
[CmdletBinding()]
param (
)
$result = $true #assume the best
$testchoco = pwsh -noprofile -c 'choco -v'
if ($testchoco[0] -like "*.*.*" -and $testchoco[0] -notlike '*not*recognized*') {
Write-Verbose -Message "Chocolatey Version: $testchoco"
}
else {
Write-Verbose -Message "Chocolatey is not installed."
$result = $false
}
return $result
} #Test-Choco
<#
.SYNOPSIS
Evaluates if WinGet is installed
#>
function Test-WinGet {
[CmdletBinding()]
param (
)
$result = $true #assume the best
$testwinget = pwsh -noprofile -c 'winget -v'
if ($testwinget[0] -like "v*") {
Write-Verbose -Message "winget Version: $testwinget"
}
else {
Write-Verbose -Message "winget is not installed."
$result = $false
}
return $result
} #Test-WinGet
<#
.SYNOPSIS
Installs chocolatey
#>
function Install-Choco {
[CmdletBinding()]
param (
)
Write-Verbose -Message 'Installing Chocolately...'
Write-Verbose -Message 'Setting execution and security settings...'
Set-ExecutionPolicy Bypass -Scope Process -Force
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
try {
Write-Verbose -Message 'Downloading and installing...'
Invoke-WebRequest https://chocolatey.org/install.ps1 -UseBasicParsing -ErrorAction Stop | Invoke-Expression -ErrorAction Stop
Write-Verbose -Message 'INSTALL COMPLETE.'
}
catch {
Write-Error $_
}
} #InstallChoco
<#
.SYNOPSIS
Installs Azure related PowerShell modules
#>
function Install-HelpfulAzureModules {
[CmdletBinding()]
param (
)
Write-Verbose -Message 'Evaluating Azure modules...'
foreach ($module in $script:azureModules) {
Write-Verbose -Message (' {0} evaluating...' -f $module)
if (-not (Get-Module $module -ListAvailable)) {
if ($module -eq 'PSArm') {
Write-Verbose -Message (' Installing {0}' -f $module)
Install-Module -Name $module -Scope CurrentUser -Repository PSGallery -AllowPrerelease -Force -AllowClobber
}
else {
Write-Verbose -Message (' Installing {0}' -f $module)
Install-Module -Name $module -Scope CurrentUser -Repository PSGallery -Force
}
}
else {
Write-Verbose -Message (' {0} VERIFIED. NO ACTION TAKEN.' -f $module)
}
}
} #Install-HelpfulAzureModules
<#
.SYNOPSIS
Installs Core PowerShell modules
#>
function Install-BaseModules {
[CmdletBinding()]
param (
)
Write-Verbose -Message 'Evaluating modules...'
foreach ($module in $script:modules) {
Write-Verbose -Message (' {0} evaluating...' -f $module.ModuleName)
if ($module.Version -like "*beta*" -or $module.Version -like "*rc*") {
Write-Verbose -Message (' {0} version check...' -f $module.Version)
$moduleEval = Get-InstalledModule -Name $module.ModuleName -RequiredVersion $module.Version -AllowPrerelease -ErrorAction SilentlyContinue
}
elseif ($module.Version -ne 'Latest') {
Write-Verbose -Message (' {0} version check...' -f $module.Version)
$moduleEval = Get-InstalledModule -Name $module.ModuleName -RequiredVersion $module.Version -ErrorAction SilentlyContinue
}
else {
$moduleEval = Get-Module -Name $module.ModuleName -ListAvailable -ErrorAction SilentlyContinue
}
if (-not $moduleEval) {
if ($module.Version -like "*beta*" -or $module.Version -like "*rc*") {
Write-Verbose -Message (' Installing {0} - {1}' -f $module.ModuleName, $module.Version)
Install-Module -Name $module.ModuleName -Scope CurrentUser -Repository PSGallery -RequiredVersion $module.Version -Force -AllowPrerelease
}
elseif ($module.Version -ne 'Latest') {
Write-Verbose -Message (' Installing {0} - {1}' -f $module.ModuleName, $module.Version)
Install-Module -Name $module.ModuleName -Scope CurrentUser -Repository PSGallery -RequiredVersion $module.Version -Force
}
else {
Write-Verbose -Message (' Installing {0}' -f $module.ModuleName)
Install-Module -Name $module.ModuleName -Scope CurrentUser -Repository PSGallery -Force
}
}
else {
Write-Verbose -Message (' {0} VERIFIED. NO ACTION TAKEN.' -f $module.ModuleName)
}
}
} #Install-BaseModules
<#
.SYNOPSIS
Uninstalls older versions of Pester that ship with Windows
#>
function Uninstall-Pester ([switch]$All) {
if ([IntPtr]::Size * 8 -ne 64) {
throw "Run this script from 64bit PowerShell."
}
$pesterPaths = foreach ($programFiles in ($env:ProgramFiles, ${env:ProgramFiles(x86)})) {
$path = "$programFiles\WindowsPowerShell\Modules\Pester"
if ($null -ne $programFiles -and (Test-Path $path)) {
if ($All) {
Get-Item $path
}
else {
Get-ChildItem "$path\3.*"
}
}
}
if (-not $pesterPaths) {
"There are no Pester$(if (-not $all) {" 3"}) installations in Program Files and Program Files (x86) doing nothing."
return
}
foreach ($pesterPath in $pesterPaths) {
takeown /F $pesterPath /A /R
icacls $pesterPath /reset
# grant permissions to Administrators group, but use SID to do
# it because it is localized on non-us installations of Windows
icacls $pesterPath /grant "*S-1-5-32-544:F" /inheritance:d /T
Remove-Item -Path $pesterPath -Recurse -Force -Confirm:$false
}
} #Uninstall-Pester
<#
.SYNOPSIS
Installs VSCode extension
#>
function Install-VSCodeExtension {
[CmdletBinding()]
param (
[string[]]$ExtensionList
)
foreach ($Extension in $ExtensionList) {
Write-Verbose -Message "Installing $Extension ..."
code --install-extension $Extension
}
}
<#
.SYNOPSIS
Evaluates if a package is installed with choco
#>
function Test-ChocoInstall {
[CmdletBinding()]
param (
# choco package to be checked for
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$ChocoPackage
)
$result = $true #assume the best
$eval = $null
Write-Verbose -Message "Checking for $ChocoPackage..."
$eval = pwsh -noprofile -c "choco list --localonly $ChocoPackage"
if ($eval -match $ChocoPackage) {
Write-Verbose -Message 'Package VERIFIED.'
}
else {
Write-Verbose -Message 'Package NOT FOUND'
$result = $false
}
return $result
} #Test-ChocoInstall
<#
.SYNOPSIS
Install choco package
#>
function Install-ChocoPackage {
[CmdletBinding()]
param (
# choco package to be installed
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$ChocoPackage
)
Write-Verbose -Message ('Choco installing - {0}' -f $ChocoPackage)
pwsh -noprofile -c "choco install $ChocoPackage -y"
} #Install-ChocoPackage
<#
.SYNOPSIS
Evaluates if a package is installed with choco
#>
function Test-WingetInstall {
[CmdletBinding()]
param (
# winget package to be checked for
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$WingetPackage
)
$result = $true #assume the best
$eval = $null
Write-Verbose -Message "Checking for $WingetPackage..."
$eval = pwsh -noprofile -c "winget list --id=$WingetPackage --exact --accept-source-agreements"
if ($eval -like "*$WingetPackage*") {
Write-Verbose -Message 'Package VERIFIED.'
}
else {
Write-Verbose -Message 'Package NOT FOUND'
$result = $false
}
return $result
} #Test-WingetInstall
<#
.SYNOPSIS
Install winget package
#>
function Install-WingetPackage {
[CmdletBinding()]
param (
# winget package to be installed
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$WingetPackage
)
Write-Verbose -Message ('winget installing - {0}' -f $WingetPackage)
pwsh -noprofile -c "winget install --id=$WingetPackage --silent --accept-package-agreements --accept-source-agreements"
} #Install-WingetPackage
<#
.SYNOPSIS
Evaluates if workstation setup files are present. If not downloads and unzips.
#>
function Get-WSSetupFiles {
[CmdletBinding()]
param (
)
$wsFilesPath = -join ($script:tempPath, '\ws_files')
Write-Verbose -Message "Evaluating if $wsFilesPath is present..."
if (-not (Test-Path $wsFilesPath)) {
Write-Verbose -Message ' Downloading workstation setup files...'
try {
$invokeSplat = @{
Uri = $script:setupFiles
OutFile = "$script:tempPath\ws.zip"
ErrorAction = 'Stop'
}
Invoke-WebRequest @invokeSplat
Write-Verbose -Message ' Download complete.'
}
catch {
Write-Error $_
return
}
try {
Write-Verbose -Message ' Expanding zip download...'
$expandSplat = @{
LiteralPath = "$script:tempPath\ws.zip"
DestinationPath = $wsFilesPath
ErrorAction = 'Stop'
}
Expand-Archive @expandSplat
Write-Verbose -Message ' UNZIPPED!'
}
catch {
Write-Error $_
return
}
}
else {
Write-Verbose -Message " VERIFIED. No action taken."
}
} #Get-WSSetupFiles
<#
.SYNOPSIS
Retrieves settings files from github and places in appropriate locations
#>
function Set-SettingsFiles {
[CmdletBinding()]
param (
)
$settings = @(
@{
Name = 'VSCode Settings'
URI = $script:vsCodeSettingsJSON
File = -join ($script:vscodeSettingsPath, '\settings.json')
}
@{
Name = 'VSCode Python Snippets'
URI = $script:vsCodePythonSnippetsJSON
File = -join ($script:vscodeSnippetsPath, '\python.json')
}
@{
Name = 'VSCode PowerShell Snippets'
URI = $script:vsCodePowerShellSnippetsJSON
File = -join ($script:vscodeSnippetsPath, '\powershell.json')
}
@{
Name = 'Windows Terminal Settings'
URI = $script:windowsTerminalSettingsJSON
File = -join ($script:windowsTerminalSettingsPath, '\settings.json')
}
@{
Name = 'oh-my-posh Settings'
URI = $script:ohmyposhJSON
File = -join ($script:ohmyposhSettings, '\.jake.omp.json')
}
@{
Name = 'PowerShell profile'
URI = $script:psProfile
# File = -join ($script:profilePath, '\profile.ps1')
File = $profile.CurrentUserAllHosts
}
)
foreach ($setting in $settings) {
Start-Sleep -Milliseconds 500
Write-Verbose -Message ('Downloading {0} to {1}' -f $setting.Name, $setting.File)
$gistUrl = $null
$fileName = $null
$gistContent = $null
$gistUrl = $setting.URI
$fileName = Split-Path $setting.File -leaf
# $path = 'C:\rs-pkgs\settings'
try {
$invokeSplat = @{
Uri = $gistUrl
ErrorAction = 'Stop'
}
$gist = Invoke-RestMethod @invokeSplat
$gistContent = $gist.Files.$fileName.Content
Write-Verbose -Message ' Download COMPLETED.'
}
catch {
Write-Error $_
continue
}
try {
Write-Verbose -Message ' Writing out content...'
$setContentSplat = @{
# Path = "$path\$fileName"
Path = $setting.File
Value = $gistContent
Confirm = $false
Force = $true
ErrorAction = 'Stop'
}
Set-Content @setContentSplat
Write-Verbose -Message ' Setting applied!'
}
catch {
Write-Error $_
continue
}
}
} #Set-SettingsFiles
<#
.SYNOPSIS
Installs all specified fonts in fonts folder
#>
function Install-Fonts {
[CmdletBinding()]
param (
)
Write-Verbose -Message 'Starting fonts installation...'
$wsFilesPath = -join ($script:tempPath, '\ws_files\ws')
$fontPath = -join ($script:tempPath, '\ws_files\ws\Fonts\Fonts')
Write-Verbose -Message ' Getting required fonts to install...'
. $wsFilesPath\Fonts\PS_Font_Scripts\Add-Font.ps1 -Path $fontPath
} #Install-Fonts
<#
.SYNOPSIS
Copies all background images for Windows terminal
#>
function Set-BackImages {
[CmdletBinding()]
param (
)
Write-Verbose -Message 'Starting Windows Terminal background files copy...'
$wsFilesPath = -join ($script:tempPath, '\ws_files\ws\backs')
Write-Verbose -Message ' Getting required backgrounds...'
$allBackgrounds = Get-ChildItem -Path $wsFilesPath
foreach ($background in $allBackgrounds) {
$testPath = -join ($script:windowsTerminalBackgroundPath, '\', $background.Name)
Write-Verbose -Message (' Evaluating - {0}' -f $background.FullName)
if (-not (Test-Path $testPath)) {
Write-Verbose -Message ' NOT found. Copying.'
Copy-Item -Path $background.FullName -Destination $testPath
}
else {
Write-Verbose -Message ' FOUND. No action taken.'
}
}
} #Set-BackImages
function Set-AzurePathVariables {
[CmdletBinding()]
param (
)
$pathsToAdd = @(
'C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator'
'C:\Program Files (x86)\Microsoft SDKs\Azure\Azcopy'
)
Write-Verbose -Message 'Backing up curent paths to file...'
$fileName = -join ('path_', (Get-Date -format yyyy-MM-ddTHH-mm-ss-ff), '.txt')
[System.Environment]::GetEnvironmentVariable('PATH', 'machine') | Out-File "$script:tempPath\$fileName" -Force
Write-Verbose -Message 'Evaluating if current paths present...'
$paths = ($env:PATH).split(";")
foreach ($pathAdd in $pathsToAdd) {
$eval = $false
foreach ($path in $paths) {
if ($path -eq $pathAdd) {
$eval = $true
Write-Verbose -Message ( '{0} Found!' -f $pathAdd)
}
}
if ($eval -eq $false) {
Write-Verbose -Message ( '{0} NOT Found! Adding...' -f $pathAdd)
$oldPath = [System.Environment]::GetEnvironmentVariable('PATH', 'machine')
$newPath = "$OLDPATH;$pathAdd"
[Environment]::SetEnvironmentVariable("PATH", "$NEWPATH", "Machine")
}
else {
Write-Verbose -Message ' No Action taken'
}
}
} #Set-AzurePathVariables
#endregion
#region main
<#
.SYNOPSIS
Sets up a new workstation for desired development configuration
.DESCRIPTION
Downloads files, settings, and configurations to set new workstation to desired development setup and config.
.EXAMPLE
Invoke-WSSetup
Configures workstation to base level dev configuration.
.EXAMPLE
Invoke-WSSetup -Python -AWS -Azure -Fonts
Configures workstation to base level dev configuration. Also adds fonts, python, aws, and azure utilities.
.PARAMETER Python
If specified installs additional Python utilities and settings
.PARAMETER AWS
If specified installs additional AWS utilities and settings
.PARAMETER AWS
If specified installs additional AWS CDK utilities for TypeScript CDK
.PARAMETER Azure
If specified installs additional Azure utilities and settings
.PARAMETER Fonts
If specified installs downloaded Nerd font packages
.NOTES
What does this actually do?
It downloads a package config zip that contains:
- Various Nerd fonts
- Background photos for Windows Terminal
Installs choco if required
Installs base level things like VSCode via choco
Downloads configuration from GitHub gists and applies to proper locations:
- Configures VSCode with desired configurations
- Populates VSCode snippets
- Sets oh-my-posh theme configuration
- Configures Windows Terminal with desired configurations
- Sets PowerShell profile.ps1
Installs base level desired PowerShell modules
Install desired VSCode extensions
Installs tech specific utilities/configs/extensions based on specified switches
#>
function Invoke-WSSetup {
[CmdletBinding()]
param (
[switch]$Software,
[switch]$Python,
[switch]$AWS,
[switch]$AWSCDK,
[switch]$Azure,
[switch]$Fonts
)
#Requires -Version 7
#Requires -RunAsAdministrator
$ProgressPreference = 'SilentlyContinue'
# verify if winget is installed
if (-not (Test-WinGet)) {
throw 'WinGet not installed. You need to install App Installer from the Microsoft Store'
}
# remove old versions of Pester
Uninstall-Pester
# set-up the temp dir if required
Write-Verbose -Message 'Verifying temp dir...'
if (-not (Test-Path $script:tempPath)) {
Write-Verbose -Message ' CREATING temp dir.'
New-Item -Path $script:tempPath -ItemType Directory -Force
}
else {
Write-Verbose -Message ' VERIFIED Temp.'
}
# make sure we have the workstation setup files
Get-WSSetupFiles
# verify chocolatey is installed
if (-not (Test-Choco)) {
Install-Choco
}
# install our base winget packages
foreach ($package in $script:wingetCoreTech) {
if (-not (Test-WingetInstall -WingetPackage $package)) {
Install-WingetPackage -WingetPackage $package
}
}
# install our base choco packages
foreach ($package in $script:chocoCoreTech) {
if (-not (Test-ChocoInstall -ChocoPackage $package)) {
Install-ChocoPackage -ChocoPackage $package
}
}
# temp add vscode path:
$env:Path += ";C:\Program Files\Microsoft VS Code\bin"
$env:Path += ";$env:LOCALAPPDATA\Programs\Microsoft VS Code\bin"
# create snippets path if not created
if (-not (Test-Path $script:vscodeSnippetsPath)) {
New-Item -Path $script:vscodeSnippetsPath -ItemType Directory -Force
}
# install our base PowerShell modules
Install-BaseModules
# install VSCode extensions
Install-VSCodeExtension -ExtensionList $script:vscodeExtensions
# download and place our settings files
Set-SettingsFiles
# copy Windows Terminal background images to proper location
Set-BackImages
# installs fonts if font switch specified
if ($fonts) {
Install-Fonts
} #if_fonts
# installs software packages if specified
if ($Software) {
foreach ($package in $script:wingetSoftwareInstalls) {
if (-not (Test-WingetInstall -WingetPackage $package)) {
Install-WingetPackage -WingetPackage $package
}
}
foreach ($package in $script:chocoSoftwareInstalls) {
if (-not (Test-ChocoInstall -ChocoPackage $package)) {
Install-ChocoPackage -ChocoPackage $package
}
}
} #if_software
# installs azure resources if azure switch is specified
if ($azure) {
# install azure winget packages
foreach ($package in $script:wingetInstallsAzure) {
if (-not (Test-WingetInstall -WingetPackage $package)) {
Install-WingetPackage -WingetPackage $package
}
}
# install azure choco packages
foreach ($package in $script:chocoInstallsAzure) {
if (-not (Test-ChocoInstall -ChocoPackage $package)) {
Install-ChocoPackage -ChocoPackage $package
}
}
# install azure Modules
Install-HelpfulAzureModules
# install azure extensions
Install-VSCodeExtension -ExtensionList $script:vscodeExtensionsAzure
# set azure path variables
Set-AzurePathVariables
} #if_azure
# installs aws resources if aws switch is specified
if ($aws) {
# install aws winget packages
foreach ($package in $script:wingetInstallsAWS) {
if (-not (Test-WingetInstall -WingetPackage $package)) {
Install-WingetPackage -WingetPackage $package
}
}
# install aws choco packages
foreach ($package in $script:chocoInstallsAWS) {
if (-not (Test-ChocoInstall -ChocoPackage $package)) {
Install-ChocoPackage -ChocoPackage $package
}
}
# install aws tools installer module
Install-Module -Name AWS.Tools.Installer -Scope CurrentUser -Repository PSGallery -Force
# install aws modules
foreach ($module in $script:awsModules) {
Write-Verbose -Message (' {0} evaluating...' -f $module)
if (-not (Get-Module $module -ListAvailable)) {
Write-Verbose -Message (' Installing {0}' -f $module)
Install-AWSToolsModule -Name $module -Scope CurrentUser -Force
}
else {
Write-Verbose -Message (' {0} VERIFIED. NO ACTION TAKEN.' -f $module)
}
}
# special case for AWSLambdaPSCore
if (-not (Get-Module 'AWSLambdaPSCore' -ListAvailable)) {
Write-Verbose -Message (' Installing {0}' -f $module)
Install-Module -Name 'AWSLambdaPSCore' -Scope CurrentUser -Repository PSGallery -Force
}
else {
Write-Verbose -Message (' AWSLambdaPSCore VERIFIED. NO ACTION TAKEN.' -f $module)
}
# install aws extensions
Install-VSCodeExtension -ExtensionList $script:vscodeExtensionsAWS
} #if_aws
# installs aws cdk resources if awscdk switch is specified
if ($awscdk) {
# install aws winget packages
foreach ($package in $script:wingetAWSCDKTypeScript) {
if (-not (Test-WingetInstall -WingetPackage $package)) {
Install-WingetPackage -WingetPackage $package
}
}
# install aws cdk useful extensions
Install-VSCodeExtension -ExtensionList $script:vscodeExtensionsAWSCDK
# temp add vscode path:
$env:Path += ";C:\Program Files\nodejs"
# Install the TypeScript compiler
npm install -g typescript
# install aws cdk library
npm install aws-cdk-lib
# install the aws cdk
npm install -g aws-cdk
}
# installs python resources if python switch is specified
if ($python) {
# install python extensions
Install-VSCodeExtension -ExtensionList $script:vscodeExtensionsPython
} #if_python
} #Invoke-WSSetup
#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment