├── LICENSE ├── Make-My-Windows.md ├── README.md ├── img └── demo.png ├── profile.ps1 ├── psaliases.ps1 └── psfunctions.ps1 /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Guozhen Li 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Make-My-Windows.md: -------------------------------------------------------------------------------- 1 | # Make My Windows 2 | 3 | ## Config Windows 4 | 5 | ### My PowerShell profile 6 | 7 | ```powershell 8 | $dest = $PROFILE.CurrentUserAllHosts 9 | if (-not (Test-Path $dest)) {New-Item $dest -Type File -Force } 10 | Split-Path $dest | Push-Location 11 | Start-BitsTransfer https://raw.githubusercontent.com/ligz08/PowerShell-Profile/master/psfunctions.ps1 12 | Start-BitsTransfer https://raw.githubusercontent.com/ligz08/PowerShell-Profile/master/profile.ps1 13 | Pop-Location 14 | . $dest 15 | ``` 16 | 17 | ## Install Software 18 | 19 | ### Visual Studio Code 20 | Download: https://code.visualstudio.com/Download 21 | 22 | ### Sublime Text 3 23 | ```powershell 24 | Start-BitsTransfer https://download.sublimetext.com/Sublime%20Text%20Build%203176%20x64%20Setup.exe 25 | & sublime*setup.exe /silent 26 | ``` 27 | 28 | ### Typora 29 | ```powershell 30 | Start-BitsTransfer https://typora.io/windows/typora-setup-x64.exe 31 | & typora-setup-x64.exe /silent 32 | ``` 33 | 34 | ### PuTTY 35 | ```powershell 36 | Start-BitsTransfer https://the.earth.li/~sgtatham/putty/latest/w64/putty-64bit-0.70-installer.msi 37 | msiexec /i 'putty-64bit-0.70-installer.msi' /passive 38 | ``` 39 | 40 | ### VirtualBox 41 | ```powershell 42 | Start-BitsTransfer https://download.virtualbox.org/virtualbox/5.2.18/VirtualBox-5.2.18-124319-Win.exe 43 | & VirtualBox-5.2.18-124319-Win.exe --silent 44 | ``` 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Guozhen's Windows PowerShell Profile 2 | ![demo](img/demo.png) 3 | 4 | ## What Is This 5 | A [PowerShell profile](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_profiles) is a script that runs every time you start a PowerShell session, such as a PowerShell console, or an integrated scripting environment (ISE). It is PowerShell's equivalent to `.bash_profile` and `.bashrc` files of the Bash shell. It's a place where you can customize your shell environment and pre-load frequently used functions/commands/variables. 6 | 7 | This repository contains my PowerShell profile scripts, including customizing the command line prompt, and useful functions like `Test-Administrator` and `Set-PathEnvironmentVariable`. 8 | 9 | The script is only tested on Windows 10 and Windows Server 2012 R2 with PowerShell 5.1. Please use caution when using it on other versions of Windows and PowerShell. Please do not use it on other operating systems. 10 | 11 | ## How To Use 12 | 13 | ### Option 1: Download the profile scripts directly to your local PowerShell profile location 14 | You can download my PowerShell-Profile scripts directly to your local machine's PowerShell profile location. 15 | Run the following script In a PowerShell console: 16 | ```powershell 17 | $dest = $PROFILE.CurrentUserAllHosts 18 | if (-not (Test-Path $dest)) {New-Item $dest -Type File -Force } 19 | Split-Path $dest | Push-Location 20 | Start-BitsTransfer https://raw.githubusercontent.com/ligz08/PowerShell-Profile/master/profile.ps1 21 | Start-BitsTransfer https://raw.githubusercontent.com/ligz08/PowerShell-Profile/master/psfunctions.ps1 22 | Start-BitsTransfer https://raw.githubusercontent.com/ligz08/PowerShell-Profile/master/psaliases.ps1 23 | Pop-Location 24 | . $dest 25 | ``` 26 | 27 | Note: the last command `. $dest` may induce an error that has to do with "Execution Policies". If this occurs, run the following commands to allow the profile scripts to run. For more details about PowerShell execution policies, see [About Execution Policies](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies). 28 | 29 | ```powershell 30 | Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser 31 | . $dest 32 | ``` 33 | 34 | ### Option 2: Clone/download repository to local machine 35 | Or, fork, clone or download this repository if you want more tweaking and customization. 36 | When on a local machine, copy all `.ps1` files to your PowerShell profile directory. For example: 37 | ```powershell 38 | Copy-Item .\*.ps1 (Split-Path $PROFILE.CurrentUserAllHosts) 39 | ``` 40 | 41 | ## More Explanations 42 | ### Current user vs. all users 43 | A profile script for "current user" is effective only for you. Not for anyone else who use a different account to log into the same machine. It is recommended to apply a profile script only for yourself (current user). 44 | 45 | ### Current host vs. all hosts 46 | A host is an application that makes calls to the PowerShell engine, and shows outputs to you. Your Windows typically has only one PowerShell core, but can have muliple hosts, for example, the PowerShell console is one, the PowerShell ISE (integrated scripting environment) is another, and the PowerShell Integrated Console in your Visual Studio Code is yet another different host. 47 | If you run `Get-Host` you can see what host you're running PowerShell from. 48 | 49 | To make different hosts behave differently, you may want to specify different profile scripts for them. Run `$PROFILE.CurretUserCurrentHost` to see where PowerShell looks for profile script for your current host. 50 | 51 | ## TODOs 52 | - [ ] `Reload-Profile` function 53 | - [ ] Help blocks & documentations for functions 54 | - [ ] Git repository status in prompt 55 | 56 | ## References & Links 57 | - This work is inspired by and borrows a lot of insights from [Mathias Bynens](https://mathiasbynens.be/)' dotfiles for macOS: https://github.com/mathiasbynens/dotfiles 58 | - About PowerShell Profiles: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_profiles 59 | - `Test-Administrator` function: https://serverfault.com/a/97599 60 | -------------------------------------------------------------------------------- /img/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ligz08/PowerShell-Profile/3e79e7862a220530d8c88a0dbe38d82ad86243a4/img/demo.png -------------------------------------------------------------------------------- /profile.ps1: -------------------------------------------------------------------------------- 1 | $tmp = $ProgressPreference 2 | $ProgressPreference = "SilentlyContinue" 3 | $computerInfo = Get-ComputerInfo 4 | $ProgressPreference = $tmp 5 | Write-Host "Operating system: $($computerInfo.OsArchitecture) $($computerInfo.OsName) version $($computerInfo.OsVersion)" 6 | Write-Host "PowerShell version: $($PSVersionTable.PSVersion)" 7 | 8 | Push-Location $PSScriptRoot 9 | 10 | Get-ChildItem ps*.ps1 | ForEach-Object {. $_.FullName} 11 | 12 | function prompt { 13 | $uiTitle = $PWD | Convert-Path | Split-Path -Leaf 14 | $Host.UI.RawUI.WindowTitle = $uiTitle 15 | Write-Host "`n$env:USERNAME" -ForegroundColor Green -NoNewline 16 | if (Test-Administrator) { 17 | Write-Host " as " -NoNewline 18 | Write-Host "Administrator" -ForegroundColor Red -NoNewline 19 | $Host.UI.RawUI.WindowTitle = $uiTitle + " (Administrator)" 20 | } 21 | Write-Host " at " -NoNewline 22 | Write-Host $env:COMPUTERNAME -ForegroundColor Magenta -NoNewline 23 | Write-Host " in " -NoNewline 24 | Write-Host $ExecutionContext.SessionState.Path.CurrentLocation -ForegroundColor Cyan -NoNewline 25 | $branch = try { git rev-parse --abbrev-ref HEAD 2>$null} catch {$null} 26 | if ($branch){ 27 | Write-Host " on " -NoNewline 28 | Write-Host $branch -ForegroundColor Yellow -NoNewline 29 | } 30 | return "`nPS $('>' * ($NestedPromptLevel + 1)) " 31 | } 32 | 33 | Pop-Location -------------------------------------------------------------------------------- /psaliases.ps1: -------------------------------------------------------------------------------- 1 | Set-Alias vs devenv 2 | Set-Alias g git 3 | Set-Alias l Get-ChildItem 4 | Set-Alias c code 5 | -------------------------------------------------------------------------------- /psfunctions.ps1: -------------------------------------------------------------------------------- 1 | 2 | function Test-Administrator { 3 | <# 4 | .Synopsis 5 | Return True if you are currently running PowerShell as an administrator, False otherwise. 6 | #> 7 | $user = [Security.Principal.WindowsIdentity]::GetCurrent() 8 | (New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) 9 | } 10 | 11 | function Get-ShortPath { 12 | [CmdletBinding()] 13 | Param ( 14 | [Parameter(Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] 15 | [string] $Path=(Get-Location) 16 | ) 17 | Begin {} 18 | Process { 19 | Write-Verbose "Make short path from: $Path" 20 | if ($Path -and (Test-Path $Path)) { 21 | $fso = New-Object -ComObject Scripting.FileSystemObject 22 | $short = if ((Get-item $Path).PSIsContainer) { 23 | $fso.GetFolder($Path).ShortPath 24 | } else { 25 | $fso.GetFile($Path).ShortPath 26 | } 27 | Write-Output $short 28 | } else { 29 | Write-Verbose "Ignoring $Path" 30 | Write-Output $null 31 | } 32 | } 33 | End {} 34 | } 35 | 36 | function Get-PathEnvironmentVariable { 37 | param ( 38 | [ValidateSet('User','Machine','All')]$Scope='All' 39 | ) 40 | <# 41 | .Synopsis 42 | Get a list of PATH environment variables. 43 | Return object has two fields: Path and Scope. 44 | Scope is either 'User' or 'Machine', suggesting whether this environment variable is available for the current user only or for all users on this machine. 45 | 46 | .Parameter Scope 47 | One of 'User', 'Machine', or 'All'. Default value 'All'. 48 | 49 | .Notes 50 | For PATH environment variable available for the current process, it is more convenient to use the $env:PATH variable. So it is not included here. 51 | This command is useful only when a path's scope (User vs. Machine) matters to you. 52 | #> 53 | 54 | $machine_paths = try { 55 | [System.Environment]::GetEnvironmentVariable('Path', 'Machine').Split(';') ` 56 | | Select-Object @{name='Path';exp={$_}},@{name='Scope';exp={'Machine'}} ` 57 | | Where-Object {$_.Path} 58 | } catch { $null } 59 | $user_paths = try { 60 | [System.Environment]::GetEnvironmentVariable('Path', 'User').Split(';') ` 61 | | Select-Object @{name='Path';exp={$_}},@{name='Scope';exp={'User'}} ` 62 | | Where-Object {$_.Path} 63 | } catch { $null } 64 | 65 | switch ($Scope) { 66 | 'User' { return $user_paths } 67 | 'Machine' { return $machine_paths } 68 | Default { return $machine_paths + $user_paths } 69 | } 70 | } 71 | 72 | function Reload-PathEnvironmentVariable { 73 | $env:Path = (Get-PathEnvironmentVariable | Select-Object -ExpandProperty Path) -join ';' 74 | } 75 | 76 | function Set-PathEnvironmentVariable { 77 | param ( 78 | [Parameter(ParameterSetName='ByList', Position=0)][string[]] $Path, 79 | [Parameter(ParameterSetName='ByString', Position=0)][string] $PathString, 80 | [ValidateSet('Process','User','Machine')] $Scope='Process' 81 | ) 82 | 83 | switch ($PSCmdlet.ParameterSetName) { 84 | 'ByList' { $paths_str = $Path -join ';' } 85 | 'ByString' {$paths_str = $PathString} 86 | Default {return} 87 | } 88 | 89 | switch ($Scope) { 90 | 'User' { 91 | try { 92 | [System.Environment]::SetEnvironmentVariable('PATH', $paths_str, 'User') 93 | } 94 | catch { 95 | Write-Host "Failed to set PATH environment variable of scope " -NoNewline 96 | Write-Host "$Scope" -ForegroundColor Yellow 97 | throw 98 | } 99 | } 100 | 'Machine' { 101 | try { 102 | [System.Environment]::SetEnvironmentVariable('PATH', $paths_str, 'Machine') 103 | } 104 | catch { 105 | Write-Host "Failed to set PATH environment variable of scope " -NoNewline 106 | Write-Host "$Scope" -NoNewline -ForegroundColor Yellow 107 | Write-Host ". Do you have Administrator privilege?" 108 | throw 109 | } 110 | } 111 | Default {$env:Path = $paths_str} 112 | } 113 | } 114 | 115 | function Add-PathEnvironmentVariable { 116 | [CmdletBinding(DefaultParameterSetName='Append')] 117 | param ( 118 | [Parameter(Position=0)][string[]]$Path, 119 | [ValidateSet('Process','User','Machine')]$Scope='Process', 120 | [Parameter(ParameterSetName='Append')][switch]$Append, 121 | [Parameter(ParameterSetName='Prepend')][switch]$Prepend, 122 | [switch]$MakeShort, 123 | [switch]$Quiet 124 | ) 125 | 126 | $machine_paths = @(Get-PathEnvironmentVariable -Scope Machine | Select-Object -ExpandProperty Path) 127 | $user_paths = @(Get-PathEnvironmentVariable -Scope User | Select-Object -ExpandProperty Path) 128 | 129 | if ($MakeShort) { 130 | $Path = $Path | Get-ShortPath 131 | } 132 | 133 | switch ($Scope) { 134 | 'User' { 135 | if ($Prepend) { 136 | $user_paths = $Path + $user_paths 137 | } else { 138 | $user_paths = $user_paths + $Path 139 | } 140 | Set-PathEnvironmentVariable -Path $user_paths -Scope 'User' -ErrorAction Stop 141 | Reload-PathEnvironmentVariable 142 | } 143 | 'Machine' { 144 | if ($Prepend) { 145 | $machine_paths = $Path + $machine_paths 146 | } else { 147 | $machine_paths = $machine_paths + $Path 148 | } 149 | Set-PathEnvironmentVariable -Path $machine_paths -Scope 'Machine' -ErrorAction Stop 150 | Reload-PathEnvironmentVariable 151 | } 152 | Default { 153 | if ($Prepend) { 154 | $env:Path = ($Path + $env:Path.Split(';') ) -join ';' 155 | } else { 156 | $env:Path = ($env:Path.Split(';') + $Path) -join ';' 157 | } 158 | } 159 | } 160 | 161 | if (-not $Quiet) { 162 | Write-Host "Added the following path(s) to PATH environment variable of scope " -NoNewline 163 | Write-Host "$Scope`n`t" -NoNewline -ForegroundColor Yellow 164 | Write-Host $Path -Separator "`n`t" -ForegroundColor Yellow 165 | } 166 | } 167 | 168 | function Remove-PathEnvironmentVariable { 169 | <# 170 | .Example 171 | Remove-PathEnvironmentVariable 'C:\Program Files\SomeProgram\bin' -Scope Machine 172 | Remove-PathEnvironmentVariable 'C:\Program Files\SomeProgram\bin','C:\Program Files\AnotherProgram\bin' 173 | 'C:\Program Files\SomeProgram\bin','C:\Program Files\AnotherProgram\bin' | Remove-PathEnvironmentVariable -Scope User 174 | #> 175 | param( 176 | [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] 177 | [string[]]$Path, 178 | [ValidateSet('Process','User','Machine')]$Scope='Process', 179 | [switch]$Force 180 | ) 181 | begin { 182 | $old_paths = switch ($Scope) { 183 | 'Process' { $env:Path -split ';' } 184 | Default { Get-PathEnvironmentVariable -Scope $Scope | Select-Object -ExpandProperty Path} 185 | } 186 | $requested_paths = @() 187 | Write-Verbose "Old paths of scope $Scope`:" 188 | $old_paths | Write-Verbose 189 | } 190 | process { 191 | $requested_paths += $Path 192 | } 193 | end { 194 | Write-Verbose "Request to remove paths:" 195 | $requested_paths | Write-Verbose 196 | $notfound_paths = $requested_paths | Where-Object {$_ -notin $old_paths} 197 | $toberemoved_paths = $requested_paths | Where-Object {$_ -in $old_paths} 198 | 199 | if ($notfound_paths) { 200 | Write-Host "Could not find the following path(s) in PATH environment variable of scope " -NoNewline 201 | Write-Host "$Scope`n`t" -NoNewline -ForegroundColor Yellow 202 | Write-Host $notfound_paths -ForegroundColor Red -Separator "`n`t" 203 | } 204 | 205 | if ($toberemoved_paths){ 206 | $new_paths = $old_paths | Where-Object {$_ -and ($_ -notin $requested_paths)} 207 | Write-Verbose "Paths to remove:" 208 | $toberemoved_paths | Write-Verbose 209 | Write-Verbose "New paths of scope $Scope`:" 210 | $new_paths | Write-Verbose 211 | try { 212 | Set-PathEnvironmentVariable -Path $new_paths -Scope $Scope 213 | } 214 | catch { 215 | return 216 | } 217 | Write-Host "Removed the following path(s) from PATH environment variable of scope " -NoNewline 218 | Write-Host "$Scope`n`t" -NoNewline -ForegroundColor Yellow 219 | Write-Host $toberemoved_paths -ForegroundColor Yellow -Separator "`n`t" 220 | } 221 | } 222 | } 223 | 224 | # TODO 225 | # function Replace-PathEnvironmentVariable {} 226 | --------------------------------------------------------------------------------